智能合约,区块链的智能合约是什么意思?
智能合约这一概念是由Nick Szabo于1994年提出,该合约被定义为“一套以数字形式定义的承诺,包括合约参与方可以在上面执行这些承诺的协议”。不同于传统合约,该合约基于区块链技术而发展智能合约、以数字为表现形式并主要通过计算机网络技术而自动执行。人们对其最为常见的认识就是将其视为是一段自动运行的代码,一段由计算机自动执行的程序,当预设的触发条件成就时合约即自动执行,相较于一般的电子合约来说更进一步。
但是,只有结合了区块链技术、分布式记账技术的代码合约才可以被视为真正的智能合约,而该合约的核心则是区块链技术。区块链技术具体表现为一种“开放的分布式数据库”,该技术使得该合约可以在一种完全公开、透明和不可被篡改的环境中运行。在这种环境的理想运作下,合约双方不再需要特定的企业来担任中间商或担保机构,所有交易都是公开透明的,即实现了“去中心化”、“去信任化”的目标。
区块链的提出使智能合约的执行获得了可信的环境,比特币交易中的输出条件是用脚本描述的,这也是智能合约的雏形。以太坊首先实现了区块链和智能合约的完美契合。
在智能合约的概念模式如图,一般而言,智能合约封装预定义的若干状态、转换规则、触发条件以及应对操作等,经各方签署后以程序代码的形式附着在区块链数据上,经对等计算机网络传播和节点验证后记入各个节点的分布式账本中,区块链可以实时监控整个智能合约的状态,在核查外部数据源确认满足特定的触发条件后激活并执行合约。
以太坊是目前开发智能合约最常用的平台,特定的基于堆栈的二进制字节码(即以太坊虚拟机字节码)组成了以太坊的智能合约。这个合约可以利用Solidity、Serpent、LLL等高级语言编写,然后编译为EVM字节码存储执行。
以太坊中智能合约是存储在以太坊区块链中特定地址的代码(功能)和数据(状态)的集合。智能合约以消息的形式在网络中传播,以太坊中合约则是存储于交易之中。EVM判断一个交易是否为合约类的依据是该交易中是否存在代码,若交易信息是代码则该合约得以执行。若在执行过程中发现某合约账户不存在则会自动创建合约地址,并将合约存入该账户。
虽然以太坊中智能合约可用于实现与比特币类似的账户余额认证方案,但其与比特币脚本程序存在显著差别:合约是图灵完备的;合约非无状态的,它们可以存储计算数据;任意合约杰克从其他合约处获取部分数据。
有人问如何用按钮调用智能合约,在这篇文章中,我将给出一个简单但有希望有效的演示,说明JavaScript开发人员如何创建一个能够调用智能合约的网页,并通过单击即可向其汇款(以太币)。
要做到这一点,用户将需要使用支持Web3的浏览器,因此可以使用像Parity或Mist这样的可安装浏览器,或者他们可以使用像MetaMask这样的浏览器扩展。
此外,虽然我可以教你如何直接使用web3API,但我将教你如何使用一个新的很方便的库与以太网智能合约EthJS交互。
你的网站需要等待ready事件,然后检查全局web3对象。看起来像这样:
window.addEventListener('load', function() {
// Check if Web3 has been injected by the browser:
if (typeof web3 !== 'undefined') {
// You have a web3 browser! Continue below!
startApp(web3);
} else {
// Warn the user that they need to get a web3 browser
// Or install MetaMask, maybe with a nice graphic.
})
从MetaMask开发人员指南中复制。
在这个例子中,我假设你正在使用像Browserify或Webpack这样的JavaScript捆绑器,并且知道如何从NPM安装模块。
在你的应用程序设置中,你将使用一些不同的ethjs模块,你将使用全局web3对象的currentProvider属性初始化它们,这就是它与区块链的对话方式。
const Eth = require('ethjs-query')
const EthContract = require('ethjs-contract')
function startApp(web3) {
const eth = new Eth(web3.currentProvider)
const contract = new EthContract(eth)
initCon
一旦实例化了合约,就可以使用它来创建对网络上实时合约的引用。要做到这一点,你需要两件事:
合约地址。
合约ABI。
ABI是应用程序二进制接口,它告诉你的JavaScript如何与智能合约通信。它只是描述合约方法的JSON数据。
通常,如果你发布合约,你知道如何获得ABI,如果你要与其他人签订合约,他们应该提供ABI,尽管有时候你可以找到与Etherscan等区块浏览器的合约相匹配的ABI。
假设你有可用的ABI和地址,并了解我们现在如何创建合约对象。在这个例子中,我将使用仅包含Token标准中的transfer(to,value)方法的ABI:
const abi = [{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
}]
const address = '0xdeadbeef123456789000000000000'
function initContract (contract) {
const MiniToken = contract(abi)
const miniToken = MiniToken.at(address)
listenForClicks(miniToken)
}
现在我们已经为智能合约初始化了一个JavaScript接口,所以我们只需要创建一个小HTML。
<button >Send Money!</button>
还有一点JavaScript来响应点击,并发送这些资金:
function listenForClicks (miniToken) {
var button = document.querySelector('button.transferFunds')
button.addEventListener('click', function() {
miniToken.transfer(toAddress, value, { from: addr })
.then(function (txHash) {
console.log('Transaction sent')
console.dir(txHash)
waitForTxToBeMined(txHash)
})
.catch(console.error)
})
}
请注意,如果此交易也发送以太,你将向包含from字段的选项哈希添加value:'10000'。该值以wei为单位,为1x10 ^ -18以太。转换的简单方法是这样的:
var inWei = web3.toWei('10', 'ether')
对于普通的Web开发人员来说,一个奇怪的部分是交易响应并不意味着交易现在已经完成,它只是意味着它已经被传输到网络。它仍然需要被挖掘,而在以太坊中,平均需要大约14秒(阻断时间,查看EthStats.net上的统计数据)。
现在还没有很好的订阅方法可以等待挖掘交易,所以你需要用收到的txHash进行轮询。是的,这很乏味,所以我会告诉你如何使用新的JavaScript async/await模式来减少痛苦:
async function waitForTxToBeMined (txHash) {
let txReceipt
while (!txReceipt) {
try {
txReceipt = await eth.getTransactionReceipt(txHash)
} catch (err) {
return indicateFailure(err)
}
}
indicateSuccess()
}
如此而已!