如何编写一个简单的智能合约(Smart Contract)

使用solidity语言编写智能合约

Ethereum 上的智能合约需要使用 solidity 语言编写。虽然还有其他能用来撰写智能合约的语言如 Serpent (类 Python )、lll (类 Fortran),但是目前看到所有公开的智能合约都是使用solidity撰写。
宣传上说,solidity是一种类JavaScript的语言,而且围绕solidity的各种开发工具链,都是使用属于JavaScript生态系统的npm来提供的,但是solidity还是比较像Java或从c#.因为和JavaScript不同,solidity与Java或C#同属于强类型(Strong Type,在定义变数时需要制定类型)语言 ,在定义函数(function)时同样需要指定回传的类型(type)、同样也需要先变异才能执行,这些特性都是JavaScript所不具备的。

开发前的准备

当前最活跃的智能合约开发框架trffle为基础来开发的,ENS(Ethereum Name Service) 也是采用truffle 框架,其他选择还有embark等

就像一般网站或App一样,在提供公共服务之前,开发者会在自己用于写程序的电脑(又称本机)或通过穿透测试网络来测试程序执行的效果,测试完成后,才会部署到公开的网络上提供服务。开发区块链智能合约(程序)的过程也是如此。特别是公开链上所有的写入或者读取计算结果的操作都是需要真金白银的(虚拟代币)。而且根据网络状况,每个公开链上的操作都需要一段反应时间(15秒~ 数分钟),这些等待非常浪费开发时间,因为在开发的过程中,我们将会使用testrpc工具在电脑上模拟智能合约所需的以太坊内存块链测试环境。

testrpc 中也包含了 JavaScript 版本的 Ethereum 虚拟机 (Ethereum Vartual Machine),因此可以完成执行智能合约。

此外,开发前的环境准备一个编辑器,推荐使用Atom配搭solidity插件来开发,solidity插件除了支持语法高亮之外,也会透过Solium检查并提示基本的语法错误,相当方便,其他编辑器应该也有类似的插件可选择。

安装所需的工具

trffle framework
官网地址: https://truffleframework.com/docs

首先在开发机上安装好Node.js,在使用以下命令安装所需的工具

    $ sudo npm install -g truffle


创建truffle 项目

$ truffle init

这里使用的是atom开发工具,打开当前项目

 $ atom ./

当前的目录结构如下

输入truffle develop进入develop控制台,并创建账号

Mac@MacdeMacBook-Pro  ~/Solidity_WorkSpace/1110/demo1  truffle develop
Truffle Develop started at http://127.0.0.1:9545/

Accounts:
(0) 0x627306090abab3a6e1400e9345bc60c78a8bef57
(1) 0xf17f52151ebef6c7334fad080c5704d77216b732
(2) 0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef
(3) 0x821aea9a577a9b44299b9c15c88cf3087f3b5544
(4) 0x0d1d4e623d10f9fba5db95830f7d3839406c6af2
(5) 0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e
(6) 0x2191ef87e392377ec08e7c08eb105ef5448eced5
(7) 0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5
(8) 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc
(9) 0x5aeda56215b167893e80b4fe645ba6d5bab767de

Private Keys:
(0) c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3
(1) ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f
(2) 0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1
(3) c88b703fb08cbea894b6aeff5a544fb92e78a18e19814cd85da83b71f772aa6c
(4) 388c684f0ba1ef5017716adb5d21a053ea8e90277d0868337519f97bede61418
(5) 659cbb0e2411a44db63778987b1e22153c086a95eb6b18bdf89de078917abc63
(6) 82d052c865f5763aad42add438569276c00d3d88a2d062d36b2bae914d58b8c8
(7) aa3680d5d48a8283413f7a108367c7299ca73f553735860a87b08f39395618b7
(8) 0f62d96d6675f32685bbdb8ac13cda7c23436f63efbb9d07700d8669ff12b7c4
(9) 8d5366123cb560bb606379f90a0bfd4769eecc0557f1b362dcae9012b548b1e5

Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

⚠️  Important ⚠️  : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.

新建一个简单的测试合约 JackyContract

pragma solidity ^0.4.23;

contract JackyContract {

  function addAToB(uint a, uint b) pure public returns (uint) {
    return a + b;
  }
}

输入编译命令

truffle(develop)> compile

在atom中,产生了一个bulid文件夹,(重写编写最好把build文件夹删除)

编译完之后,会在build文件夹产生对应的json文件。

编写测试用例

test目录下,新建一个TestJackyContract.sol文件

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/JackyContract.sol";

contract TestJackyContract {
  function testJackyAdd() {
    JackyContract jackyContract = JackyContract(DeployedAddresses.JackyContract());

    Assert.equal(jackyContract.addAToB(1,3),4,"1 + 3 should be 4");
  }

}

然后在truffle develop控制台输入test

效果图如下,说明测试通过

如果测试不通过将显示下图信息

部署

migration文件下,创建一个js部署文件,注意的是开头一定要以数字开头的

migration目录下新建部署脚本2_deployed_jacky.js

var JackyContract = artifacts.require("./JackyContract.sol");

module.exports = function(deployer) {
  deployer.deploy(JackyContract);
};

然后在truffle develop控制台输入 migrate

其中的JackyContract就是我们部署的合约地址

JackyContract: 0x4e72770760c011647d4873f60a3cf6cdea896cd8

接下来我们验证一下是否与部署的字节码相同,调用web3获取字节码,与json文件中的字节码是相同的。

truffle(develop)> web3.eth.getCode('0x4e72770760c011647d4873f60a3cf6cdea896cd8')
'0x608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680637c329899146044575b600080fd5b348015604f57600080fd5b5060766004803603810190808035906020019092919080359060200190929190505050608c565b6040518082815260200191505060405180910390f35b60008183019050929150505600a165627a7a723058209a73f7769aa3866b57fc9f39b67383c1f87f9c082db63a71d5d0f4b7574dc1530029'

获取合约的实例

let contract

JackyContract.deployed().then(instance => contract = instance

控制机输入 变量contract 可以看见相关的合约,获取到合约实例就可以调用里面的方法了

contract.addAToB(3,2)

合约互动

ps:这里需要注意的是,如果function 加了 pure 或者是 constant 就可以直接调用,但是没有加 pure,调用的时候还需要call

参考:
web3.js官方文档
solidity官方文档
Ethereum电子书

猜你喜欢

转载自blog.csdn.net/q282176713/article/details/81229092