Hands-On Blockchain for Python Developers
上QQ阅读APP看书,第一时间看更新

Going deeper into Vyper

Let’s take a look at our smart contract:

name: public(bytes[24])

@public
def __init__():
self.name = "Satoshi Nakamoto"

@public
def change_name(new_name: bytes[24]):
self.name = new_name

@public
def say_hello() -> bytes[32]:
return concat("Hello, ", self.name)

Take a look at the first line:

name: public(bytes[24])

The array of bytes is basically a string. The variable called name has a type of array of bytes or string. Its visibility is public. If you want to set it to private, then just omit the public keyword, as follows:

name: bytes[24]

Now, take a look at the next lines:

@public
def __init__():
self.name = “Satoshi Nakamoto”

If you are coming from a Python background, then you will recognize the Python decorator function. There are four of these in Vyper:

  • @public means you can execute this method as a user (just as you did in the Truffle console in the previous chapter).
  • @private means that only other methods inside the same smart contract can access this method. You cannot call the method as a user (in the Truffle console).
  • @payable means that you can send some ethers to this method.
  • @const is an indicator that this method should not modify the state of a smart contract. It means that it will not cost ether to execute this method. It’s like reading a public variable's value.

Going back to the __init__() method, you could pass a parameter to this method like this:

i: public(uint256)

@public
def __init__(int_param: uint256):
self.i = int_param

Don't forget to send the parameter when you deploy a smart contract. In our case, we use migration in Truffle software, so modify your migration file, 2_deploy_hello.js, to be as follows:

var Hello = artifacts.require("Hello");
module.exports = function(deployer) {
deployer.deploy(Hello, 4);
};

Let’s move on to the following lines of the smart contract to understand the public method:

@public
def change_name(new_name: bytes[24]):
self.name = new_name

This method modifies the state of the smart contract, which is the name variable. This would incur gas.

Let’s move on to the next lines of the smart contract to learn about returning a value inside the public method:

@public
def say_hello() -> bytes[32]:
return concat("Hello, ", self.name)

A concat is a built-in function that combines the strings. Refer to https://vyper.readthedocs.io/en/latest/built-in-functions.html for a complete list of built-in functions.

You must be careful with the return value of the method indicated by the right arrow (→). You might set this to an array of bytes that does not have enough length. For example, take a look at the following code:

@public
def say_hello() -> bytes[28]:
return concat("Hello, ", self.name)

In this case, it would fail in compilation, although "Hello, Satoshi Nakamoto" is definitely less than 28 characters. The string has a length of 23 characters; however, you must remember that self.name is defined as bytes[24], and Hello,   has a length of 7 characters. Because 24 + 7 is 31 characters, you must set this to a bigger array.

Since this method does not change the state of this smart contract, you can add @const on top of this method, as follows:

@public
@const
def say_hello() -> bytes[32]:
return concat("Hello, ", self.name)