Login
欢迎来到未来世界

您现在的位置是: 首页 > 计算机 > 区块链

区块链

智能合约-Solidity官方文档(1)(智能合约架构)

区块链 加入收藏
想必现在有很多小伙伴对于智能合约-Solidity官方文档(1)方面的信息都比较想要了解,那么今天小好小编就为大家收集了一些分享给大家,希望大家会喜欢哦。写在前面:HiBlock区块链社区成立了翻译小组(以太坊中文社区),翻译区块链相关的技术

想必现在有很多小伙伴对于智能合约-Solidity官方文档(1)方面的信息都比较想要了解,那么今天小好小编就为大家收集了一些分享给大家,希望大家会喜欢哦。

写在前面:HiBlock区块链社区成立了翻译小组(以太坊中文社区),翻译区块链相关的技术文档及资料,本文为solidity官方文档翻译的第一部分《智能合约概述》,特发布出来邀请solidity爱好者、开发者做公开的审校,您可以添加微信baobaotalk_com,验证输入“solidity”,然后将您的意见和建议发送给我们,也可以在文末“留言”区留言,有效的建议我们会采纳及合并进下一版本,同时将送一份小礼物给您以示感谢。

1简单的智能合约让我们先看一下最基本的例子。

现在就算你都不理解也不要紧,后面我们会有更深入的讲解。

存储pragma solidity ^0.4.0;contract SimpleStorage {uint storedData;function set(uint x) public {storedData = x;}function get() public constant returns (uint) {return storedData;}}第一行就是告诉大家源代码使用Solidity版本0.4.0写的,并且使用0.4.0以上版本运行也没问题(最高到0.5.0,但是不包含0.5.0)。

这是为了确保合约不会在新的编译器版本中突然行为异常。

关键字pragma的含义是,一般来说,pragmas(编译指令)是告知编译器如何处理源代码的指令的(例如,pragma once)。

Solidity中合约的含义就是一组代码(它的函数)和数据(它的状态),它们位于以太坊区块链的一个特定地址上。

代码行uintstoredData;声明一个类型为uint(256位无符号整数)的状态变量,叫做storedData。

你可以认为它是数据库里的一个位置,可以通过调用管理数据库代码的函数进行查询和变更。

对于以太坊来说,上述的合约就是拥有合约(owning contract)。

在这种情况下,函数set和get可以用来变更或取出变量的值。

要访问一个状态变量,并不需要像this.这样的前缀,虽然这是其他语言常见的做法。

该合约能完成的事情并不多(由于以太坊构建的基础架构的原因):它能允许任何人在合约中存储一个单独的数字,并且这个数字可以被世界上任何人访问,且没有可行的办法阻止你发布这个数字。

当然,任何人都可以再次调用set,传入不同的值,覆盖你的数字,但是这个数字仍会被存储在区块链的历史记录中。

随后,我们会看到怎样施加访问限制,以确保只有你才能改变这个数字。

子货币(Subcurrency)例子下面的合约实现了一个最简单的加密货币。

这里,币确实可以无中生有地产生,但是只有创建合约的人才能做到(实现一个不同的发行计划也不难)。

而且,任何人都可以给其他人转币,不需要注册用户名和密码 —— 所需要的只是以太坊密钥对。

pragma solidity ^0.4.21;contract Coin {// 关键字“public”让这些变量可以从外部读取address public minter;mapping (address => uint) public balances;// 轻客户端可以通过事件针对变化作出高效的反应event Sent(address from, address to, uint amount);// 这是构造函数,只有当合约创建时运行function Coin() public {minter = msg.sender;}function mint(address receiver, uint amount) public {if (msg.sender != minter) return;balances[receiver] += amount;}function send(address receiver, uint amount) public {if (balances[msg.sender] < amount) return;balances[msg.sender] -= amount;balances[receiver] += amount;emit Sent(msg.sender, receiver, amount);}}这个合约引入了一些新的概念,让我们逐一解读。

addresspublicminter;这一行声明了一个可以被公开访问的address类型的状态变量。

address类型是一个160位的值,且不允许任何算数操作。

这种类型适合存储合约地址或外部人员的密钥对。

关键字public自动生成一个函数,允许你在这个合约之外访问这个状态变量的当前值。

如果没有这个关键字,其他的合约没有办法访问这个变量。

由编译器生成的函数的代码大致如下所示:function minter() returns (address) { return minter; }当然,加一个和上面完全一样的函数是行不通的,因为我们会有同名的一个函数和一个变量,这里,主要是希望你能明白——编译器已经帮你实现了。

下一行,mapping(address=>uint)publicbalances;也创建一个公共状态变量,但它是一个更复杂的数据类型。

该类型将address映射为无符号整数。

Mappings 可以看作是一个哈希表它会执行虚拟初始化,以使所有可能存在的键都映射到一个字节表示为全零的值。

但是,这种类比并不太恰当,因为它既不能获得映射的所有键的列表,也不能获得所有值的列表。

因此,要么记住你添加到mapping中的数据(使用列表或更高级的数据类型会更好),要么在不需要键列表或值列表的上下文中使用它,就如本例。

而由public关键字创建的getter函数getter function则是更复杂一些的情况, 它大致如下所示:function balances(address _account) public view returns (uint) {return balances[_account];}正如你所看到的,你可以通过该函数轻松地查询到账户的余额。

eventSent(addressfrom,addressto,uintamount);这行声明了一个所谓的“事件(event)”,它会在send函数的最后一行被发出。

用户界面(当然也包括服务器应用程序)可以监听区块链上正在发送的事件,而不会花费太多成本。

一旦它被发出, 监听该事件的listener都将收到通知。

而所有的事件都包含了from,to和amount三个参数,可方便追踪事务。

为了监听这个事件,你可以使用如下代码:Coin.Sent().watch({}, '', function(error, result) {if (!error) {console.log("Coin transfer: " + result.args.amount +" coins were sent from " + result.args.from +" to " + result.args.to + ".");console.log("Balances now:\n" +"Sender: " + Coin.balances.call(result.args.from) +"Receiver: " + Coin.balances.call(result.args.to));}})这里请注意自动生成的balances函数是如何从用户界面调用的。

特殊函数Coin是在创建合约期间运行的构造函数,不能在事后调用。

它永久存储创建合约的人的地址:msg(以及tx和block) 是一个神奇的全局变量,其中包含一些允许访问区块链的属性。

msg.sender始终是当前(外部)函数调用的来源地址。

最后,真正被用户或其他合约所调用的,以完成本合约功能的方法是mint和send。

如果mint被合约创建者外的其他人调用则什么也不会发生。

另一方面,send函数可被任何人用于向他人发送币 (当然,前提是发送者拥有这些币)。

记住,如果你使用合约发送币给一个地址,当你在区块链浏览器上查看该地址时是看不到任何相关信息的。

因为,实际上你发送币和更改余额的信息仅仅存储在特定合约的数据存储器中。

本文到此结束,希望对大家有所帮助。

图集详情底部广告位