区块链学堂(14):Browser-solidity 5–Token基于账户的代币合约

基于账户地址的Token合约

pragma solidity 0.4.9;
contract Token {
  mapping (address => uint) public balancesOf;
  function Token() {
    balancesOf[msg.sender] = 10000;
  }
}

mapping 关键词的定义

Mapping types are declared as mapping(_KeyType => _ValueType). Here _KeyType can be almost any type except for a mapping, a dynamically sized array, a contract, an enum and a struct. _ValueType can actually be any type, including mappings.

Mappings can be seen as hashtables which are virtually initialized such that every possible key exists and is mapped to a value whose byte-representation is all zeros: a type’s default value. 引用自here

address的定义:

address: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as base for all contracts.
members of addresses: balance and send
引用自here

这里的address简单地说就是geth中的账户的地址(公钥)
因此此处的代码mapping (address => uint) balancesOf 代表定义了一个 key为address类型, value为uint类型的hashtable,名字为 balancesOf.

所以任何在区块链私链上的账户都可以通过balancesOf[address] 来查询他们的代币数量。

msg 的定义

msg就是指谁调用该智能合约时候发来的信息,之前说过智能合约也是一个账户。因此在以太坊中调用智能合约从底层看来就是一个账户给智能合约账户发送了一个transaction,里面包含了谁发送的,发送了多少以太币,发送了多少gas
下面是msg的一些变量

msg.data (bytes): complete calldata
msg.gas (uint): remaining gas
msg.sender (address): sender of the message (current call)
msg.sig (bytes4): first four bytes of the calldata (i.e. function identifier)
msg.value (uint): number of wei sent with the message 引用自here

最主要的就是msg.sender,代表那个账户调用该智能合约。msg.value

  • 因此balancesOf[msg.sender] = 10000; 代表给msg.sender也就是创建该合约的地址赋予一个初始值 10000;

一个带transfer & 挖矿的Token合约

pragma solidity 0.4.9;
contract Token {
  mapping (address => uint) public balancesOf;
  address public owner;
  function Token() {
    owner = msg.sender;
    balancesOf[msg.sender] = 10000;
  }

  function transfer(address _to, uint _value) {
    if (balancesOf[msg.sender] < _value) throw; //避免转移出去的代币超过当前的存货
    if (balancesOf[_to] + _value < balancesOf[_to]) throw; //避免自己调用自己,或者递归调用
    balancesOf[msg.sender] -= _value;
    balancesOf[_to] += _value;
  }

  function mint(uint _amount) {
    balancesOf[owner] += _amount;
  }
}
  • 在上面的代码中,我们设置一个public owner, 保存下创建合约的msg.sender, 记录下创建者的地址。
  • function transfer()中,我们设置了两个条件,避免转移出去的代币超过存货的情况,以及自己转移给自己的问题。
  • function mint()中,我们给合约的owner增加我们定义的代币。从而让其方便的分给别人。
以上合约代码在Browser-solidity上调试通过,查看下图

区块链学堂(14):Browser-solidity 5–Token基于账户的代币合约_第1张图片

  • 我们在代码中将owner = msg.sender,因此owner就是创建合约的地址。我们可以看到balancesOf[owner] 的数据为10000,和代码相同。

区块链学堂(14):Browser-solidity 5–Token基于账户的代币合约_第2张图片

  • 调用方法mint(500),自动给balancesOf[owner] += 500;查看存额从10000增加到10500.

区块链学堂(14):Browser-solidity 5–Token基于账户的代币合约_第3张图片

  • 调用方法 transfer("0xccccc",300), 可以看到owner的存额减少300,balancesOf[“0xccccc”]增加300.

区块链学堂(14):Browser-solidity 5–Token基于账户的代币合约_第4张图片

这个合约实现了最简化的代币功能,但在browser-solidity中我们可以看到一个很明显的问题,那就是没有和我们在第二部分中所搭建的geth中的几个以太坊账号结合起来。

下一章我们将介绍另一个非常有用的工具Mist,从而将智能合约、Geth、Mist结合起来。真正在以太坊私有链上运行智能合约。


QQ群:559649971 (区块链学堂粉丝群)
个人微信:steven_k_colin

获取最新区块链咨询,请关注《以太中文网》微信公众号:以太中文网

你可能感兴趣的:(区块链)