一个简单的智能合约
首先来看个简单的例子
pragmasolidity^0.4.0;
contractSimpleStorage {
uint storedData;
function set(uintx) {
storedData=x;
}
function get() constant returns(uint) {
returnstoredData;
}
}
pragmasolidity^0.4.0;//verson 0.4.0 or不破坏功能的newer verson (except 0.5.0),为了确保合同不会突然对新的编译器版本有不同的行为
在solidity意义上,合约是驻留在以太坊区块链傻姑娘的特定地址的代码(功能)和数据(状态)的集合。
要访问状态变量,不需要this.前缀
这个合同还没有做太多的事情(由于以太坊建造的基础设施),允许任何人存储一个单一的数字,世界上任何人都可以没有(可行的)一种方式阻止你发布这个数字。当然,任何人都可以set再次调用不同的值,并覆盖你的数字,但数字仍将存储在blockchain的历史。稍后,我们将看到如何强制实施访问限制,以便只有您可以更改号码。
Subcurrency示例
以下合同将实现加密货币的最简单形式。可以从稀薄的空气中生成硬coins,但只有创建合同的人才能够做到这一点(实施不同的发行计划很简单)。此外,任何人都可以相互发送coins,而不需要使用用户名和密码注册,只需要一个以太坊的密钥对。
pragma solidity^0.4.0;
contractCoin {
// The keyword "public" makes those variables
// readable from outside.
address public minter;
mapping(address=>uint)public balances;
// Events allow light clients to react on
// changes efficiently.
eventSent(addressfrom,addressto,uintamount);
// This is the constructor whose code is
// run only when the contract is created.
functionCoin() {
minter=msg.sender;
}
function mint(address receiver,uint amount) {
if(msg.sender!=minter)return;
balances[receiver]+=amount;
}
function send(address receiver,uint amount) {
if(balances[msg.sender]
balances[msg.sender]-=amount;
balances[receiver]+=amount;
Sent(msg.sender, receiver, amount);
}
}
address public minter ;声明了可公开访问的类型为address的状态变量
address类型是160bit(位)的值,不允许有任何操作运算,适合存储属于外部人员的合同或密钥对的地址。
public关键字自动生成一个函数,允许您访问状态变量的当前值。函数如下所示:function minter() returns(address) {return minter; }
mapping(address=>uint)public balances; 这个类型将地址映射到无符号整数。映射可以被看作是哈希表,其被虚拟地初始化,使得每个可能的键存在并且映射到其字节表示全部为零的值。getter方法如下:
function balances(address _account) returns (unit){
Return balances[_account];
}
event Sent(address from,address to,uint amount);用户界面(以及服务器应用程序)监听在区块链上发射的事件不用太多代价。一旦被激活,监听器会获取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));
}
})
特殊方法Coin是在创建合同期间运行的构造函数,之后不能被调用。它永久地存储创建合同的人的地址:msg(和tx、block)为全局变量,包含一些运行访问区块链的属性。msg.sender是当前(外部)方法调用的地址。
最后,像mint和send这些方法会以合约结束,然后可以被用户和合约调用。如果mint除了创建合同的账户之外的任何人调用,任何事情都不会发生。send可由任何人(已有一些硬币)向其他人发送硬币。注意,如果你使用这个合同向一个地址发送coins,你不会在区块链explorer上看到该地址的任何内容。因为你发送coins和更改余额的事实仅存储在这份特定coin合约的数据存储中。通过使用事件,创建一个跟踪新coin交易和余额的“blockchainexplorer”相对容易
区块链基础
区块链技术对于程序员来说不会很难理解,原因是大多数并发症(采矿,散列,椭圆曲线加密,对等网络...)都在提供一定的功能和承诺
交易
区块链是一个全球共享的事务型数据库。意味着每个参与到这个网络中的人都可以从数据库中读取条目。如果你想改变数据库中的数据,你需要创建一个被所有其他人接受的事务。交易这个词代表着你想要做的改变(假使你想要在同一时间改变两个值)不是完全被执行或者被应用的。同时,一旦你的交易被应用到数据库,别的交易不能改变它。
交易的处理满足数据库的原子性
此外,一次交易总是被发送方(创建者)加密签名。这直接保护了对数据库的特殊修改。在电子货币例子中,简单的检查确保只有持有账户密钥的人才能从中转帐
区块
需要克服的主要障碍在比特币术语中称为“双重花费攻击”,如果网络中存在两个交易都想清空一个账户,发生冲突,会发生什么?
交易的顺序会为你决定选择哪个,这些交易会被绑定到区块中,它们会被执行和分发到所有参与的节点。如果两个交易相互矛盾,那么第二笔交易将会被拒绝,而不是成为这个交易的一部分。
这些块在时间上形成一个线性序列,这也是“区块链”一词的来源。块以相当规则的间隔添加到链中-对于Ethereum大概是17秒。
作为“订单选择机制”(被称为“采矿”)的一部分,可能会发生块不时地回滚,但仅仅发生在区块链的顶部。顶部区块添加的越多,越不可能。所以你可能将你的交易回滚甚至从区块链中移除,但是你等待的时间越长,可能性越小。