什么是智能合约 ?
智能合约是一种特殊协议,在区块链内制定合约时使用,当中内含了程式码函式 (Function),亦能与其他合约进行互动、做决策、储存资料及传送以太币等功能。智能合约主力提供验证及执行合约内所订立的条件。智能合约允许在没有第三方的情况下进行可信交易。这些交易可追踪且不可逆转。智能合约概念于1994年由一名身兼电脑科学家及密码学专家的学者尼克·萨博首次提出。智能合同的目的是提供优于传统合同方法的安全,并减少与合同相关的其他交易成本。
关键信息
- 它是一种协议(话外音:一种行为操作行为规范)
- 在区块链内使用 (话外音:目前也只在区块链范围内使用)
- 允许在没有第三方的情况下进行可信交易(话外音:若将银行比作第三方,那就是没有银行的作保的情况下交易,这个厉害)
- 交易可追踪但不可逆(话外音:我的理解是有记账的,账本上写的可是清清楚楚)
Hello, World
先从一个小小示例一步步理解什么是智能合约
环境安装
Mac下使用brew
进行安装
brew tap ethereum/ethereum
brew install ethereum
启动以太坊开发节点
➜ geth --datadir testNet --dev console 2>> test.log
Welcome to the Geth JavaScript console!
instance: Geth/v1.9.6-stable/darwin-amd64/go1.13.1
coinbase: 0x8b061a00c065a2dfd6942d86846d3b4b786917de
at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
datadir: /Users/fun/Desktop/eth/hello/testNet
modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0
>
准备账户
系统里面有一个默认账户余额很多
> eth.accounts
["0x8b061a00c065a2dfd6942d86846d3b4b786917de"]
> eth.getBalance(eth.accounts[0])
1.15792089237316195423570985008687907853269984665640564039457584007913129639927e+77
>
我们来新建一个账户
> personal.newAccount("pi")
"0xceb1ec23fdce1fa5bab08c6c5e54ea0fbc6649ab"
注意,pi
为新账户的密码,这下系统里面就有俩账户
> eth.accounts
["0x8b061a00c065a2dfd6942d86846d3b4b786917de", "0xceb1ec23fdce1fa5bab08c6c5e54ea0fbc6649ab"]
些时新账户还没有钱,我们从默认账户转一一个以太币给新账户
> eth.sendTransaction({from: '0x8b061a00c065a2dfd6942d86846d3b4b786917de', to: '0xceb1ec23fdce1fa5bab08c6c5e54ea0fbc6649ab', value: web3.toWei(1, "ether")})
"0xa5f60e32ec9b776fc84a2f4d691c905712e6ded011044c5e6c90c2652e1fc7c5"
解锁新账户
> eth.getBalance(eth.accounts[1])
1000000000000000000
> personal.unlockAccount(eth.accounts[1],"pi")
true
这一步是为了后续的智能合约做准备
编写合约代码
pragma solidity ^0.4.18;
contract hello {
string greeting;
function hello(string _greeting) public {
greeting = _greeting;
}
function say() constant public returns (string) {
return greeting;
}
}
image.png
注意红框处标出的编译器版本要与代码里面兼容,至少保持一致,若使用本例代码,可直接点此链接
部署合约
image.png点击左侧红框按钮,拷贝右侧
WED3DEPLOY
下边紧邻代码,并将第一行注释部分修改为为字符串,将from: web3.eth.accounts[0]
(默认账户)改为from: web3.eth.accounts[1]
(我们的新建账户), 如下所示
var _greeting = "hello world" ;
var helloContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"say","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]);
var hello = helloContract.new(
_greeting,
{
from: web3.eth.accounts[1],
data: '0x6060604052341561000f57600080fd5b6040516102a33803806102a3833981016040528080519091019050600081805161003d929160200190610044565b50506100df565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061008557805160ff19168380011785556100b2565b828001600101855582156100b2579182015b828111156100b2578251825591602001919060010190610097565b506100be9291506100c2565b5090565b6100dc91905b808211156100be57600081556001016100c8565b90565b6101b5806100ee6000396000f3006060604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663954ab4b28114610045575b600080fd5b341561005057600080fd5b6100586100cf565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561009457808201518382015260200161007c565b50505050905090810190601f1680156100c15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100d7610177565b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561016d5780601f106101425761010080835404028352916020019161016d565b820191906000526020600020905b81548152906001019060200180831161015057829003601f168201915b5050505050905090565b602060405190810160405260008152905600a165627a7a723058200db3e1dda4a6bb1f41135beedcfe47e61676f1ad575ea7df4080140a14a85b1c0029',
gas: '4700000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
将代码复制粘贴至geth
控制台
Contract mined! address: 0x51f053559a75ebeb33f2ddb2a0a120c060315900 transactionHash: 0x404731ceb41f1a36178f297d534610e1fa03e817043bb2c3c87cca1939f914dc
此时合约已部署完成,看一下此时我们的新建账户的余额
> eth.getBalance(eth.accounts[1])
999999999999827811
钱少了
> 1000000000000000000 - 999999999999827811
172160
运行合约
合约内容如下
> hello
{
abi: [{
constant: true,
inputs: [],
name: "say",
outputs: [{...}],
payable: false,
stateMutability: "view",
type: "function"
}, {
inputs: [{...}],
payable: false,
stateMutability: "nonpayable",
type: "constructor"
}],
address: "0x51f053559a75ebeb33f2ddb2a0a120c060315900",
transactionHash: "0x404731ceb41f1a36178f297d534610e1fa03e817043bb2c3c87cca1939f914dc",
allEvents: function(),
say: function()
}
运行之
> hello.say()
"hello world"
虽然运行正常,但也有诸多不解之处
- 合约固然有交易双方,抛开其它细节,合约只看到有
from
账户,却没有to
账户? - 合约完成后
from
账户金额减少了172160
小于合约中的gas
数值4700000
? - 这是一个示例智能合约,只是为了演示,从
Solidity
代码看几乎什么也没做,为何会有金额的减少? - 目前觉得智能合约智在没有第三方监管与担保,如何有效执行?
以上是对智能合约的观感,虽说近日看了许多关于区块链的文章,主要是李笑来老师以及一些白皮书,但是想要清楚的讲解区块链却备感艰难,遂干脆从代码入手,自己给自己提问,暂时摒弃细节,望后续的学习能解今日之惑。
Refer:
网友评论