创建和编译智能合约

本文详细介绍如何从零开始搭建智能合约开发环境,包括安装必要工具、使用Truffle框架创建及部署首个智能合约,并实现简单的功能交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址https://yq.aliyun.com/articles/212944

学习目标

  1. 了解智能合约
  2. 简单环境搭建
  3. 能够利用solidity编写Hello World合约
  4. 合约部署
  5. 和合约互动

使用solidity语言撰写智能合智能合约的语言如Serpent(类Python)、lll(类Fortran),但目前看到所有公开的智能合约都是使用solidity撰写。

和Javascript不同,solidity与Java或C#同属于强类型(Strong Type,在定义变数时需要指定类型)语言、在定义函式(function)时同样需指定回传的类型(type)、同样也需要先编译才能执行。这些特性都是Javascript所不具备的。

开发前的准备

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

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

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

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

安装所需工具

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

$ npm install -g ethereumjs-testrpc truffle

启动Testrpc

安装好后随时可以使用testrpc命令来启动以太坊测试环境。

[root@localhost Code]# testrpc
EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)

Available Accounts
==================
(0) 0xd7b3b49796cfd47052c4a67629b1e0fe9c09d26e
(1) 0x1d592bd42f9ea941c29a49815f9cc70ad7a56e27
(2) 0xe5fd35e9d0ad57e86d6fdaf1adaa1a9284455c75
(3) 0xa146608867e4bb8dffb5f18e077f15e2206729d7
(4) 0x798eb7d614b8551006e59bcb9d0f8f7a65fcc940
(5) 0x0cffe71365e86ff01e64a1e645d5c58dcc452e9b
(6) 0xaf7db0a16f38b726d88e0178de15b863a9ab9999
(7) 0x5f54e3068d32a40c275543ea6f6c1100171303e6
(8) 0xf960dc2847187319ee430b3329960ea12292c1cb
(9) 0x74cf710f4542147999a732c7195124d369ebb287

Private Keys
==================
(0) 9bd1a2aff40833670cead04323c0a855dd86b24456074c954099a995b9405be2
(1) 96b3ec627bc8b6a3e9ab8028590dd80956e72194b1f47b7b4e986df128cd555f
(2) 5d81798a274e8842c7bbe0e07db25ad830c933b0b399b432cc851d93b365106c
(3) a9f2442706e6096fa799e69a80b8f742443df45def427124785bc35db0a7b21e
(4) 74f48c3d893d2686a849820f37b6ada312d4dbb91284c1dccf70d509d083b14a
(5) da327b3996bd73ed4de4d8dba231bf3213a98d81dec443dc0271caa5775c3124
(6) f739d18d8a3b886439475a8ad6a81f56b1fa3ba2dd339c797e07999397b834b3
(7) 7051aa205dfaab958a4db6f427574cd8a0fe4119a5f3acf0b7bb1887767c40b0
(8) 958947167492194982678c0858ada43841cf5df45a88d1e3832b405e24720ad0
(9) 1f89c302b3762b84ade76f97815177b61a5c8631f45b6c242aca4e26022142f3

HD Wallet
==================
Mnemonic: march casual surround shine tennis blur liberty oblige tennis save vault mistake
Base HD Path: m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

 

可以看到testrpc启动后自动建立了10个帐号(Accounts),与每个帐号对应的私钥(Private Key)。每个帐号中都有100个测试用的以太币(Ether)。要注意testrpc仅运行在內存中,因此每次重开时都会回到全新的状态。

一切准备就绪,我们可以开始建立第一份智能合约项目了。

建立项目

开启另一个终端窗口,输入以下命令以建立项目:

[root@localhost admin]# cd Code
[root@localhost Code]# ls
blockchain test-contract
[root@localhost Code]# mkdir SmartContractDemo
[root@localhost Code]# cd SmartContractDemo/
[root@localhost SmartContractDemo]# mkdir HelloWorld
[root@localhost SmartContractDemo]# cd HelloWorld/

[root@localhost HelloWorld]# truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

Compile: truffle compile
Migrate: truffle migrate
Test contracts: truffle test

目录结构:

/contracts:存放智能合约原始代码的地方,可以看到里面已经有三个sol文件,我们开发的HelloWorld.sol文件就存放在这里。

/migrations:这是 Truffle用来部署智能合约的功能,待会儿我们会修改2_deploy_contracts.js来部署 HelloWorld.sol
/test: 测试智能合约的代码放在这里,支持js 与 sol 测试。
truffle.js: Truffle 的设置文档。

对truffle.js添加内容:要不然之后会报一个错

module.exports = {
    networks: {
        development: {
            host: "localhost",
            port: 8545,
            network_id: "*" // 匹配任何network id
         }
    }
};

新建HelloWorld合约

contracts文件夹下新建HelloWorld.sol文件,当然也可以直接在HelloWorld路径下面直接执行truffle create contract HelloWorld命令来创建HelloWorld.sol

[root@localhost HelloWorld]# ls
contracts migrations test truffle-config.js truffle.js
[root@localhost HelloWorld]# truffle create contract HelloWorld
[root@localhost HelloWorld]# ls contracts/
HelloWorld.sol Migrations.sol
[root@localhost HelloWorld]# gedit contracts/HelloWorld.sol

 

HelloWorld.sol文件內容如下:

pragma solidity ^0.4.4;

contract HelloWorld {
  function sayHello() returns (string) {
    return ("Hello World");
  }
}

讲解

pragma solidity ^0.4.4; 第一行指名目前使用的solidity版本,不同版本的solidity可能会编译出不同的bytecode^代表兼容solidity`0.4.4 ~ 0.4.9`的版本。
contract HelloWorld {
    ...
}

contract关键字类似于其他语言中较常见的class。因为solidity是专为智能合约(Contact)设计的语言,声明contract后即内置了开发智能合约所需的功能。也可以把这句理解为class HelloWorld extends Contract

function sayHello() returns (string) {
    return ("Hello World");
}

函数的结构与其他程序类似,但如果有传入的参数或回传值,需要指定参数或回传值的类型(type)。

编译

现在执行truffle compile命令,我们可以将HelloWorld.sol原始码编译成Ethereum bytecode

[root@localhost HelloWorld]# ls
build contracts migrations test truffle-config.js truffle.js
[root@localhost HelloWorld]# cd build
[root@localhost build]# ls
contracts
[root@localhost build]# cd contracts/
[root@localhost contracts]# ls
HelloWorld.json Migrations.json
[root@localhost contracts]# cat HelloWorld.json

中间很长,结尾是:

编译成功后,会在HelloWorld文件夹下面的build/contracts文件夹下面看见HelloWorld.json文件。

[root@localhost contracts]# ls
HelloWorld.json Migrations.json

部署

truffle框架中提供了方便部署合约的脚本。打开migrations目录创建2_deploy_contracts.js文件(脚本使用Javascript编写)

[root@localhost HelloWorld]# cd migrations/
[root@localhost migrations]# ls
1_initial_migration.js
[root@localhost migrations]# gedit migrations/2_deploy_contracts.js

将内容修改如下:

var HelloWorld = artifacts.require("HelloWorld");
module.exports = function(deployer) {
  deployer.deploy(HelloWorld);
};

使用artifacts.require语句来取得准备部署的合约。使用deployer.deploy语句将合约部署到区块链上。这边HelloWorldcontract的名称而不是文件名。因此可以用此语法读入任一.sol文件中的任一合约。

现在执行truffle migrate命令:

如此一来合约已经部署到testrpc中。切换到testrpc窗口,可以看到testrpc有反应了。

 

与合约互动

truffle提供命令行工具,执行truffle console命令后,可用Javascript来和刚刚部署的合约互动。

[root@localhost HelloWorld]# ls
build contracts migrations test truffle-config.js truffle.js
[root@localhost HelloWorld]# truffle console
truffle(development)> HelloWorld.deployed().then(instance => contract = instance)

讲解
HelloWorld.deployed().then(instance => contract = instance)

truffle console中预载了truffle-contract函数库,以方便操作部署到区块链上的合约。

这边使用HelloWorld.deployed().then语句来取得HelloWorld合约的Instance(实例),并存到contract变量中,以方便后续的调用。

上面用的是Javascript ES6+的语法,这句也可以写成:

HelloWorld.deployed().then(instance => {
    contract = instance
});

还可以用ES5的写法:

HelloWorld.deployed().then(function(instance) {
  hello = instance;
});
truffle(development)> contract.sayHello.call()
'Hello World'

这里直接呼叫contract.sayHello()也会得到一样的结果。truffle-contract提供使用call()来读取只读(read only)的数据,这样就不需提供gas。因此如果遇到的操作需要向区块链写入数据,我们就不能用call语句了。

如此一来,我们已写好并部署完成了第一个智能合约,也验证了合约确实可以运作。

加入新方法

我们在HelloWorld.sol中再加入一个echo方法,echo方法接受输入一个参数,并回传传送的参数。

[root@localhost HelloWorld]# ls
build contracts migrations test truffle-config.js truffle.js
[root@localhost HelloWorld]# gedit contracts/HelloWorld.sol

function echo(string name) constant returns (string) {
    return name;
}

新的echo方法中传入了一个name参数。我们也为echo方法加入一个constant声明,表示调用这个方法并不会改变区块链的状态。如此一来,透过truffle-contract来调用此方法时,会自动选用call来呼叫,也不需要额外提供gas。

由于更新了合约内容,我们需要先重新新编译一次,将编译结果部署到testrpc上,再透过truffle console执行看看结果。

[root@localhost HelloWorld]# truffle compile

[root@localhost HelloWorld]# truffle migrate --reset

[root@localhost HelloWorld]# truffle console
truffle(development)> let contract
undefined
truffle(development)> HelloWorld.deployed().then(instance => contract = instance)

echo方法确实将我们输入的内容回传了。同时因为声明了constant,我们不需要直接调用call()方法,truffle会自动选用call来呼叫。

另一点需要注意的,是这次如果还是用truffle migrate命令,我们会得到如下信息:

$ truffle migrate
Using network 'development'.
Network up to date.

Truffle会告诉你现在网络上的合约都已是最新的,但事实上刚刚程序中新增的方法并没有更新到内存块链上。要更新内存块链上已部署的程序,需要改写migrations中的脚本,但现在还不到介绍migration的时候。还好我们开发用的内存块链是怎么修改都没关系的testrpc,可以使用truffle migrate --reset命令直接重新在testrpc上部署一次。

总结

这篇文章非常简单,通过这篇文章,你将掌握如何配置开发环境、如何创建新项目、如何编译、如何部署合约以及了解整个智能合约开发的流程。

转载于:https://www.cnblogs.com/ycx95/p/9183090.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值