1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 pragma solidity ^0.5.1;
// 定义代币合约
contract Coin {
// 定义一个公共的地址类型变量,名为minter(铸币者),只有TA才能生成代币
address public minter;
// 定义一个映射关系,类似于key-value的关系,保存了某个地址下代币数量的一个关系
mapping (address => uint) public balances;
// 交易发生的消息事件
event Sent(address from, address to, uint amount);
// 构造函数,只会在合约部署的时候执行一次。谁部署了合约,谁就是铸币者
constructor() public{
minter = msg.sender;
}
// 铸币功能
function mint(address receiver, uint amount) public {
// 如果调用此方法的不是铸币者,那么就会直接退出。
if (msg.sender != minter) return;
// 铸币者给接收者(receiver)的账户上添加代币,保存在balances中
balances[receiver] += amount;
}
// 转账功能
function send(address receiver, uint amount) public {
// 检测调用此方法的账户,是否有足够的余额可以进行转账交易
if (balances[msg.sender] < amount) return;
// 先扣除转账者的代币
balances[msg.sender] -= amount;
// 再给接收者增加相应的代币数
balances[receiver] += amount;
// 发送交易成功的消息推送
emit Sent(msg.sender, receiver, amount);
}
}
此合约定义了Coin,并在构造函数中确定了合约的部署者即为当前代币合约的铸币者。
我们这样来理解,假设有:
账户A:0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
账户B:0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
账户C:0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db
如果通过账户A部署了Coin合约,那么账户A就为该合约里的铸币者。此时也会生成一个合约的地址,这是区分不同合约的一个标识,这里可以类比为Java中实例对象的内存地址。(意思是:相同的一套合约代码,不同的账户部署了该合约,得到的合约地址是不一样的,生成的代币也是不一样的,而且是不互通,不能相互转账的。即使是相同的账户多次去部署同样的一份合约代码,也会生成不同的合约地址。这也就解释了为什么合约一旦发布,就不能修改的问题,因为合约已经存到区块链上了,区块链上的内容是不能修改的。)
此时,账户A可以调用mint() 方法进行铸币,铸币可以给自己,也可以给他人。即:mint方法的receiver参数,可以是A自己的账户地址,也可以是他人的地址。
如果账户B和C去调用了mint()方法,会在铸币者校验那里通不过,直接返回。
账户A、B、C都能调用send() 方法,只要有足够的余额,就可以给接收者进行代币转账。