想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】
链客,有问必答!!
以太坊区块链技术2.0版本对于行业应用的开发最主要特性就是实现了智能合约,本质上讲智能合约是由事件驱动的、
具有状态的、运行在一个复制的、分享的账本之上的、且能够保管账本上资产的程序。
它是一个可以被信任,总是按照事先的规则执行的操作。但与此同时,智能合约部署完之后无法修改也会带来其他问题,这是另一个议题。下面直接上干货。
本篇内容是基于go客户端通过命令行完成智能合约的编写、发布、调用。
可参考的项目地址:http://www.ethdocs.org/en/latest/contracts-and-transactions/contracts.html
1、安装solidity智能合约开发语言
[plain] view plain copy
brew tap ethereum/ethereum
brew install solidity
which solc
2、打开命令行,进入之前创建的私链,并设置日志输出文件
[plain] view plain copy
jwter-WIFI:csdnBlog jwter$ geth --datadir “privateChain” console 2>> log_output
Welcome to the Geth JavaScript console!
instance: Geth/v1.4.18-stable-c72f5459/darwin/go1.7.3
coinbase: 0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9
at block: 164 (Sat, 03 Dec 2016 16:29:24 CST)
datadir: privateChain
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
3、设置编译环境
[plain] view plain copy
web3.eth.getCompilers()
[“Solidity”]
admin.setSolc("/usr/local/bin/solc")
“solc, the solidity compiler commandline interface\nVersion: 0.4.2+commit.af6afb04.Darwin.appleclang
\n\npath: /usr/local/bin/solc”
4、编写智能合约并编译
[plain] view plain copy
contractSource = “contract test { function multiply(uint a) returns(uint d) { return a * 7; } }”
“contract test { function multiply(uint a) returns(uint d) { return a * 7; } }”
contract = eth.compile.solidity(contractSource).test
{
code: “0x606060405260308060106000396000f3606060405260e060020a6000350463c6888fa18114601c575b6002565b3
46002576007600435026060908152602090f3”,
info: {
abiDefinition: [{
constant: false,
inputs: […],
name: “multiply”,
outputs: […],
payable: false,
type: “function”
}],
compilerOptions: “–bin --abi --userdoc --devdoc --add-std --optimize -o /var/folders/c6/
1vhz7hcd7w9g883rwrn4vzvr0000gn/T/solc271136546”,
compilerVersion: “0.4.2”,
developerDoc: {
methods: {}
},
language: “Solidity”,
languageVersion: “0.4.2”,
source: “contract test { function multiply(uint a) returns(uint d) { return a * 7; } }”,
userDoc: {
methods: {}
}
}
}
单源编译器输出会给出你合约对象,每个都代表一个单独的合约。eth.compile.solidity 的实际返还值是合约名字到合约对象的映射。由于合约名字是test,eth.compile.solidity(source).test会给出包含下列领域的测试合约对:
Code 编译的以太坊虚拟机字节代码
Info 从编译器输出的额外元数据
Source 源代码
Language 合约语言 (Solidity,Serpent,LLL)
LanguageVersion 合约语言版本
compilerVersion 用于编译这个合约的solidity编译器版本。
abiDefinition 应用的二进制界面定义
userDoc 用户的NatSpec Doc。
developerDoc 开发者的NatSpec Doc。
编译器输出的直接结构化(到code和info)反映了两种非常不同的部署路径。编译的以太坊虚拟机代码和一个合约创建交易被发送到区块,剩下的(info)在理想状态下会存活在去中心化云上,公开验证的元数据则执行区块链上的代码。
如果你的源包含多个合约,输出会包括每个合约一个入口,对应的合约信息对象可以用作为属性名称的合约名字检索到。你可以通过检测当前的GlobalRegistrar代码来试一下:
contracts = eth.compile.solidity(globalRegistrarSrc)
5、定义智能合约abi并编译
[plain] view plain copy
abi = [{constant:false , inputs:{name:‘a’,type:‘uint256’}}]
[{
constant: false,
inputs: {
name: “a”,
type: “uint256”
}
}]
myabi = eth.contract(abi)
6、部署前准备:解锁账户、监控日志文件
[plain] view plain copy
accountAddress = eth.accounts[0]
“0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9”
personal.unlockAccount(accountAddress)
Unlock account 0x56a957bbde2b2dcb6321c9aceb11c21d6dfe68f9
Passphrase:
true
监控日志文件需新开窗口,执行以下命令。用于查看部署完的智能合约是否被同步到区块链网路中
[plain] view plain copy
jwter-WIFI:csdnBlog jwter$ tail -f log_output
7、部署智能合约
[plain] view plain copy
myContract = myabi.new({from:accountAddress,data:contract.code})
{
abi: [{
constant: false,
inputs: {
name: “a”,
type: “uint256”
}
}],
address: undefined,
transactionHash: “0xf330f4affd3989d72a979410e3a53f3a4d2d4d832faaa6c1bb32f72998acbd4b”
}
8、查看部署状态,并同步到区块链中智能合约必须开始挖矿模式才是被同步到区块链中
可根据监控日志窗口可以看到交易是否执行,来决定何时执行miner.stop()
[plain] view plain copy
txpool.status
{
pending: 1,
queued: 0
}
miner.start()
true
miner.stop()
true
txpool.status
{
pending: 0,
queued: 0
}
9、调用智能合约
[plain] view plain copy
contractABI = eth.contract(contract.info.abiDefinition)testContract = contractABI.at(myContract.address)
{
abi: [{
constant: false,
inputs: [{…}],
name: “multiply”,
outputs: [{…}],
payable: false,
type: “function”
}],
address: “0xcb0895d4b3b35b2a45a31fab853614c14e7759a4”,
transactionHash: null,
allEvents: function(),
multiply: function()
}
testContract.multiply.call(3)
21
注意:记得保存智能合约部署完的地址,以及abi参数,因为部署完之后无法修改,
忘记地址则无法再次调用,同时部署智能合约会消耗gas,完成后可观察用户的余额是否变化。