Solidity合约初识

本文将通过一个简单的合约代码示例,对代码结构进行说明。

代码示例

如下代码所示,这是蚂蚁区块链合约平台对积分管理方案的简单实现,主要实现了积分的发放、转账和查询三个方法。

  1. pragma solidity ^0.4.0;
  2. contract CreditManager {
  3. int256 creditLimit = 1000000000; // the issue limit
  4. int256 issueAmount = 0; // the issue total amount
  5. identity admin; // the administrator in contract
  6. mapping(identity=>int256) credit;
  7. event IssueEvent(identity indexed to, int256 indexed value);
  8. event TransferEvent(identity indexed from, identity indexed to, int256 indexed value);
  9. function CreditManager() {
  10. admin = msg.sender;
  11. }
  12. // modifier
  13. modifier onlyAdmin() {
  14. require(msg.sender == admin,"Permission denied");
  15. _;
  16. }
  17. // issue credit and only admin can
  18. function Issue(identity account, int256 value) public onlyAdmin returns(bool) {
  19. // the value should bigger than 0, and issueAmount add value should small than issueAmount
  20. require(issueAmount + value <= creditLimit && issueAmount + value > issueAmount && value > 0, "Invalid value!");
  21. credit[account] += value;
  22. issueAmount += value;
  23. IssueEvent(account,value);
  24. return true;
  25. }
  26. function Transfer(identity account,int256 value) public returns(bool) {
  27. require(credit[msg.sender] >= value, "balance not enough!");
  28. require(value > 0 && value <= creditLimit, "Invalid value!");
  29. credit[msg.sender] -= value;
  30. credit[account] += value;
  31. TransferEvent(msg.sender,account,value);
  32. return true;
  33. }
  34. function Query(identity account) public returns(int256) {
  35. return credit[account];
  36. }
  37. }

代码分析

声明合约版本

首先,合约需要声明其版本,合约具体实现以 contract 关键字声明开始。

如下代码所示(截取自上述代码示例,下同),蚂蚁区块链合约平台基于 Solidity 的 0.4.24 版本进行了修改与设计,支持 0.4.24 版本之前的各种特性。

  1. pragma solidity ^0.4.0;
  2. contract CreditManager {

声明变量

本合约示例中,定义了两个变量来保存积分的总量(creditLimit)和目前发放的数量(issueAmount),并使用 identity 类型来标注每一个用户的身份,如合约的管理员(admin)账户,identity 的长度为 32 字节,每个 identity 在区块链上具有唯一性,所以合约通过 identity 来标注用户的积分。

  1. int256 creditLimit = 1000000000; // the isuue limit
  2. int256 issueAmount = 0; // the issue total amount
  3. identity admin; // the administrator in contract
  4. mapping(identity=>int256) credit;

声明事件

本合约示例中,声明了两个事件来记录对应的方法执行的情况,一个是积分发放的事件记录(IssueEvent),另一个则是积分转账的事件记录(TransferEvent)。

  1. event IssueEvent(identity indexed to, int256 indexed value);
  2. event TransferEvent(identity indexed from, identity indexed to, int256 indexed value);

构造函数

在构造函数中,设置合约管理员(admin)账户 ID,再使用关键字 modifier 设置管理员权限。(点击查看关键字的具体介绍)

  1. function CreditManager() {
  2. admin = msg.sender;
  3. }
  4. // modifier,when mas.sender != admin, the contract will show "Permission denied" in output
  5. modifier onlyAdmin() {
  6. require(msg.sender == admin,"Permission denied");
  7. _;
  8. }

定义实现方法

本示例中,合约实现了积分的发放、转账和查询方法。

如下代码所示,在调用积分发放方法中,通过 onlyAdmin 来保证发放操作只能通过管理员来进行,然后向用户传入的账户中增加相应的积分,发放过程中需要注意积分的溢出问题,发放完毕后,可以触发积分发放事件,用户可以在调用合约发放方法结果的日志中看到该事件记录。

  1. // issue credit and only admin can
  2. function Issue(identity account, int256 value) public onlyAdmin returns(bool) {
  3. // the value should bigger than 0, and issueAmount add value should small than issueAmount
  4. require(issueAmount + value <= creditLimit && issueAmount + value > issueAmount && value > 0, "Invalid value!");
  5. credit[account] += value;
  6. issueAmount += value;
  7. IssueEvent(account,value);
  8. return true;
  9. }

合约的转账与发放类似,但是转账不需要有管理员权限即可执行,查询积分也是一样。