solidity智能合约编程(进阶)

1)合约转账三种方式:

1. address.transfer(uint256 acount):失败抛出异常(触发revert),发送2300gas,不可调节;
2. address.send((uint256 acount):失败返回false,发送2300gas,不可调节;
3. address.call.value(uint256 acount)():失败返回false,发送全部gas,可调节(.gas(uint256 gasAmount));

2)tx.origin与msg.sender区别:

交易调用顺序:A->B->C
tx.origin:最初发起交易的地址(上面交易中对于C来说,tx.origin为A地址);tx.origin可用于拒绝中间合约来调用当前合约;
msg.sender:当前调用者地址(上面交易中对于C来说,msg.sender为B地址);

3)强行将以太币置入合约:

1. 自毁selfdestruct(address):从合约地址删除所有字节码,并将所有存储在该合约的ether发送到指定地址(若目的地址是合约地址,不会调用fallback函数);
2. 预先发送的ether:由于合约地址是根据部署该合约的账户地址和创建合约的交易Nonce(创建者地址执行了多少次交易)的哈希值计算得出,address(keccak256(0xd6, 0x94, _from, nonce));因此,可以预先计算出地址,并发送ether到改地址。
3. 挖矿

4)异常处理三种方式:

1. require(判断条件):只能用于测试内部数据;验证是否正确;条件不满足,退出函数;新版后,不消耗任何gas;
2. revert():验证可能出现的异常,触发异常就回退,相当于:
//检查是否出现这种不满足的条件
if (amount > msg.value / 2 ether)
            revert("Not enough Ether provided.");
// 下边是等价的方法来做同样的检查:
 require(amount <= msg.value / 2 ether,"Not enough Ether provided." );
3. assert():可用于条件检查,条件不满足抛出异常;多用于溢出检查,常数检查;

5)三种常见拒绝服务攻击(DOS):

1. 依赖外部状态改变的结果作为函数继续执行的条件:攻击者利用攻击合约fallback函数中revert(),使得原合约条件一直无法满足;
攻击合约fallback函数:
    //当前回退函数;无法接受ether
    function() external payable{
        revert();//标记错误,回滚当前调用
    }
原合约判断条件:
require(_receiver.send(acount));//_receiver:退回ether地址
2. gas limit发动DOS:
以太坊规定了每一个区块所能花费的gas limit,如果超过交易便会失败。
3. owner用户保管不善

6)内部和外部地址:

用户创建的账户地址称为:外部地址;外部地址具有私钥,用户可以访问。
建立在以太坊上的合约地址称为内部地址;内部地址不能直接作为钱包访问,只能通过调用其功能使用。

7)三个合约之间交互和调用的函数

1. call: 最常用的调用方式,调用后内置变量 msg 的值会修改为调用者,执行环境为被调用者的运行环境(合约的 storage)。

2. delegatecall: 调用后内置变量 msg 的值不会修改为调用者,但执行环境为调用者的运行环境。

3. callcode: 调用后内置变量 msg 的值会修改为调用者,但执行环境为调用者的运行环境。

通过delegatecall调用的目标地址的代码要在当前合约的环境中执行,也就是说它的函数执行在被调用合约部分其实只用到了它的代码,所以这个函数主要是方便我们使用存在其他地方的函数。


 

你可能感兴趣的:(智能合约,区块链,智能合约,安全,solidity)