1、UXTO是什么?
UXTO是Unspend Transaction Output,字面意思就是不需要花费的交易输出。有几个典型缺点:
-
价值盲(Value-blindness)。UTXO脚本不能为账户的取款额度提供精细的控制。例如,预言机合约(oracle contract)的一个强大应用是对冲合约,A和B各自向对冲合约中发送价值1000美元的比特币,30天以后,脚本向A发送价值1000美元的比特币,向B发送剩余的比特币。虽然实现对冲合约需要一个预言机(oracle)决定一比特币值多少美元,但是与现在完全中心化的解决方案相比,这一机制已经在减少信任和基础设施方面有了巨大的进步。然而,因为UTXO是不可分割的,为实现此合约,唯一的方法是非常低效地采用许多有不同面值的UTXO(例如对应于最大为30的每个k,有一个2k 的UTXO)并使预言机挑出正确的UTXO发送给A和B。
-
缺少状态 – UTXO只能是已花费或者未花费状态,这就没有给需要任何其它内部状态的多阶段合约或者脚本留出生存空间。这使得实现多阶段期权合约、去中心化的交换要约或者两阶段加密承诺协议(对确保计算奖励非常必要)非常困难。这也意味着UTXO只能用于建立简单的、一次性的合约,而不是例如去中心化组织这样的有着更加复杂的状态的合约,使得元协议难以实现。二元状态与价值盲结合在一起意味着另一个重要的应用,取款限额,是不可能实现的。
-
区块链盲(Blockchain-blindness)- UTXO看不到区块链的数据,例如随机数和上一个区块的哈希。这一缺陷剥夺了脚本语言所拥有的基于随机性的潜在价值,严重地限制了博彩等其它领域应用。
2、地址Address
Address在solidity是一种特殊的类型,有20字节,表示一个账户(普通用户账户或者合约账户)。
Address成员:
- balance,查询地址的余额
- transfer,向地址转账,如果是合约地址,合约的回退函数会随transfer一起执行,如果是gas消耗完,失败会抛出异常
- send,与transfer对应,向地址转账,单位是wei,失败返回false
- call,底层接口,用来向合约发送一个消息,失败返回false。一个例外是:如果第一个参数恰好4个字节,在这种情况下,会被认为根据ABI协议定义的函数器指定的函数签名而直接使用。如果仅想发送消息体,需要避免第一个参数是4个字节。如下面的例子:
address nameReg = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
nameReg.call("register", "MyName");
nameReg.call(bytes4(keccak256("fun(uint256)")), a);
call()
的返回结果即使成功,并不能说操作成功了,只是没有出现异常,比如我们第一个例子中,实际是调用到了fallback()
函数。
- delegatecall,与
call
的功能类似,区别仅在于后者仅使用给定地址的代码,其它信息则使用当前合约(如存储,余额等等)。delegatecall()方法的目的是用来执行另一个合约中的库代码。所以开发者需要保证两个合约中的存储变量能兼容,来保证delegatecall()能顺利执行。
call,delegatecall都是底层的调用函数,不建议直接使用,因为破坏了solidity的类型安全。
3、以太币支付
payable标识的函数:如果一个函数需要进行以太币交易,必须带上payable,这样才能正常接收msg.value
合约的fallback(),每一个合约有且仅有一个没有名字的函数。这个函数无参数,也无返回值。如果调用合约时,没有匹配上任何一个函数(或者没有传哪怕一点数据),就会调用默认的回退函数。一般在执行send函数时,会默认关联到fallback(),用于send失败的回退操作。Solidity中当签名不匹配任何的函数方法时,将会触发回退函数
4、函数
solidity中函数的关键字是function。函数的返回值可以是多个,函数体上关键字是returns,函数内部是return。
pragma solidity ^0.4.0;
contract Simple {
//使用`return`关键字指定返回值
function output1(uint a, uint b) returns (uint r){
return a + b;
}
//省略返回参数的变量名定义
function output2(uint a, uint b) returns (uint){
return a + b;
}
function output4(uint a, uint b) returns (uint mul){
mul = a * b;
//不能混合使用两种定义方式
//使用`return`时要返回所有定义
//Untitled3:18:9: Error: Different number of arguments in return statement than in returns declaration.
return 1;//1
}
//返回多个值
function returnMul(uint a) returns (uint, uint){
return (a, a + 1);
}
}
函数的可见性:
external:
- 声明为
external
的可以从其它合约或通过Transaction
进行调用,所以声明为external
的函数是合约对外接口的一部分。 - 不能以
internal
的方式进行调用。 - 有时在接收大的数据数组时性能更好。
public:
- 函数默认声明为
public
。 public
的函数既允许以internal
的方式调用,也允许以external
的方式调用。public
的函数由于被外部合约访问,是合约对外接口的一部分。
internal:
- 在当前的合约或继承的合约中,只允许以
internal
的方式调用。
private:
- 只能在当前合约中被访问(不可在被继承的合约中访问)。
- 声明为
private
,仍能被所有人查看到里面的数据。访问权限只是阻止了其它合约访问函数或修改数据。