solidity develops Ethereum token smart contracts

Smart contract development is one of the cores of Ethereum programming, and tokens are a key link in blockchain applications. Let's use the solidity language to develop an example of a token contract, hoping to help everyone.

The application of Ethereum is called decentralized application (DApp). The development of DApp mainly includes two parts:

  • Development of smart contracts
  • User interface development

In this article, we will introduce solidity, the development language for smart contracts.

Let's start with a very basic example, don't worry you don't understand it at all, we'll learn more details step by step.

contract SimpleStorage {
    uint storedData;

    function set(uint x) {
        storedData = x;
    }

    function get() constant returns (uint retVal) {
        return storedData;
    }
}

In Solidity, a contract consists of a set of code (the function of the contract) and data (the state of the contract). The contract is located at a special address on the Ethereum blockchain.

uint storedData; This line of code declares a state variable named storedData of type uint (256bits unsigned integer). You can think of it as a storage unit in the database, just like the management database, you can query and modify it by calling functions. In Ethereum, usually only the owner of the contract can do this. In this example, the functions set and get are used to modify and query the value of a variable, respectively.

As in many other languages, there is no need to add a prefix like this. to access state variables.

This contract can't do much yet (limited by Ethereum's infrastructure), just allow anyone to store a number. And anyone in the world can access the number, lacking a (reliable) way to protect the numbers you publish. Anyone can call the set method to set a different number over the number you posted. But your numbers will remain in the history of the blockchain. Later we will learn how to add an access limit so that only you can change this number.

Write a token contract

The next contract will implement a cryptocurrency in its simplest form. Anyone can send currency to other people without registering a username and password, as long as they have a pair of Ethereum public and private keys.

contract Coin {
//关键字“public”使变量能从合约外部访问。
    address public minter;
    mapping (address => uint) public balances;

//事件让轻客户端能高效的对变化做出反应。
    event Sent(address from, address to, uint amount);

//这个构造函数的代码仅仅只在合约创建的时候被运行。
    function Coin() {
        minter = msg.sender;
    }
    function mint(address receiver, uint amount) {
        if (msg.sender != minter) return;
        balances[receiver] += amount;
    }
    function send(address receiver, uint amount) {
        if (balances[msg.sender] < amount) return;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Sent(msg.sender, receiver, amount);
    }
}

This contract introduces some new concepts, let's introduce them one by one.

address public minter;

This line of code declares a publicly accessible state variable of type address. The value of type address has a size of 160 bits and does not support any arithmetic operations. Suitable for storing the contract's address or other people's public and private keys. The public keyword automatically generates access functions for its modified state variables. Variables without the public keyword will not be accessible by other contracts. In addition, only the code in this contract can be written. The automatically generated function is as follows:

function minter() returns (address) { return minter; }

Of course, it is not feasible for us to add such an access function ourselves. The compiler will complain that the function has the same name as a state variable.

The next line of code creates a public state variable, but with a more complex type:

mapping (address => uint) public balances;
This type maps some addresses to unsigned integers. Mapping can be thought of as a hash table, and the value corresponding to each possible key is virtually initialized to all 0s. This analogy is not very strict. For a mapping, it is impossible to obtain a linked list containing all its keys or values. So we have to remember what to add to the mapping. A better way is to maintain a linked list like this, or use some other higher-level data type. Or use mapping only in scenarios that are not affected by this flaw, like this example. In this example, the access function generated by the public keyword will be more complicated, and its code is roughly as follows:

function balances(address _account) returns (uint balance) {
    return balances[_account];
}

We can easily query the balance of a specific account through this function.

event Sent(address from, address to, uint value); 

This line of code declares an "event". Triggered by the last line of code in the send function. Clients (and server applications as well) can listen to these blockchain-triggered events with very little overhead. When the event is triggered, the listener will receive the from, to, value parameters at the same time, which can be easily used to track transactions. To listen for this event, you can use the following code:

Coin.Sent().watch({}, '', function(error, result) {
    if (!error) {
        console.log("Coin transfer: " + result.args.amount +
            " coins were sent from " + result.args.from +
            " to " + result.args.to + ".");
        console.log("Balances now:\n" +
            "Sender: " + Coin.balances.call(result.args.from) +
            "Receiver: " + Coin.balances.call(result.args.to));
    }
}

Note how the auto-generated balances function is called in the client.

There is a special function Coin here. It is a constructor that runs when the contract is created and cannot be called afterwards. It will permanently store the address of the contract creator. msg (along with tx and block) is a magic global variable that contains some blockchain-specific properties that can be accessed by contract code. msg.sender always holds the address of the external caller of the current function.

Finally, the functions that are actually called by users or other contracts to complete the functions of this contract are mint and send. If someone other than the contract creator calls mint, nothing happens. And send can be called by anyone (with a certain amount of tokens) to send some coins to others. Note that when you send some tokens to an address via this contract, querying that address in a blockchain explorer will see nothing. Balance changes due to sending a token are only stored in the data store for that token contract. Through events we can easily create a "blockchain explorer" that can track your new currency transactions and balances.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324814744&siteId=291194637