兄弟们,真的是我,我又回来了。经历了懒散与加班的日子,让我们一起继续智能合约的征程吧。废话不多说,直接上干货。
在以太坊中,有两种类型的账户:一种是外部账户(EOAs,Externally Owned Accounts),另一种是合约账户(Contracts Accounts)。当我们提到账户这个术语的时候,我们通常指的是外部账户(EOA),当提到合约账户的时候我们通常称其为“合约”。
而以太坊的地址分为两种,普通地址和合约地址
如下图所示,标识1的地方就是我们的外部账户地址,而标识2就是我们的合约地址:
下面我们来看一段代码:
pragma solidity ^0.4.16;
contract AddressTest{
address public account;
//0xca35b7d915458ef540ade6068dfe2f44e8fa733c
//0x692a70d2e424a56d2c6c27aa97d1a86395877b3a
address public account1 = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;
address public account2 = 0x692a70d2e424a56d2c6c27aa97d1a86395877b3a;
function changeIt() view returns(uint160){
return uint160(account1); //1154414090619811796818182302139415280051214250812
}
function changeIt2() view returns(address){
return address(1154414090619811796818182302139415280051214250812);
}
}
操作上述代码之后,我们发现:我们的地址的确是一个160字节的数字。uint160和地址之间的转换也是相当地丝滑。另外我们可以看到上述代码中的account1
和account2
是有一个大小关系的,明显是account1
大于account2
.是的,没错,我们的地址是可以比较大小的。大家都是有经验的开发人员,在这里我们就不演示这个东东了。
这一小节,我们来说说以太坊转账。没有吃过猪肉 ,总见过猪跑吧。虽然我们没有用以太坊转过账,但是应该会听说过前几天币圈暴跌的新闻,还有币所在交易高峰拔网线的传闻。导致大家没有办法交易,也可以说是没有办法进行转账操作。再具体了解以太坊转账之前,我们先来看看这么一个关键字payable
。
pragma solidity ^0.4.16;
contract payableTest{
//payable 关键字代表我们可以通过这个函数给我们的合约充值
function pay() payable{
}
}
那么假如我们没有这个payable
关键字 行不行呢? 思考两秒钟。
去掉payable
关键字之后,我们发现会报错如下:
transact to payableTest.pay errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value. Debug the transaction to get more information
翻译过来 就是需要这个关键字的意思。
上面我们已经将钱转到了我们的合约里面,但是我们该怎么拿到这个钱呢?这就要说一个属性叫做balance
我们来看看如下代码:
pragma solidity ^0.4.16;
contract payableTest{
function pay() payable{
}
function getBalance() returns(uint){
return this.balance;
}
}
如此一来,我们就成功完成了一笔转账。
上节我们看到通过this.balance
获取到了合约的余额。我们接触过一些编程语言都知道,this
一般就指示的是类的对象,那我在合约中,他代表什么呢?我们来看如下代码:
//0x5e72914535f202659083db3a02c984188fa26e9f 合约地址
//0x0971B5d216af52c411C9016BBc63665b4E6f2542 this
function getThis() view returns(address) {
return this;
}
部署执行后,我们发现this 就是一串地址。且就等于我们的合约地址。那么就很好理解了,this.balance
拿的就是合约里面的money。
那么,如此类推的话,我们是不是也可以通过函数的方式拿到账户钱包的地址呢?答案是显然的。
function getAccountBalance(address account) view returns(uint){
return account.balance;
}
复制钱包地址后执行getAccountBalance
方法后,我们便可以得到钱包里的余额,和我们上面显示的余额一致呦。相信到这里,大家对合约及账户有了更清晰的认识。
上节我们学习了如何将钱包里面的钱转到合约里面去,但是我们如果想跨钱包(或者可以说是跨账户)去转账,该怎么做呢?这里我们就要引入一个函数。没错,就是我们的transfer
函数。下面我们继续来看一段代码。
pragma solidity ^0.4.16;
contract transferTest{
//注意转账 需要添加payable关键字
function transfer(address account) payable{
account.transfer(msg.value);
}
}
我们的操作步骤如下:
如此一来,你就可以向你的好兄弟或者女友转账啦~
上面我们学习了如何进行账户间转账,那么我们如何利用transfer
将账户的钱转账到合约里面呢?
这里需要有点有技巧,我们先直接看代码
pragma solidity ^0.4.16;
contract transferTest{
function transfer() payable{
this.transfer(msg.value);
}
function () payable{
}
}
上述直接用一个括号()
表示的函数,我们在这里叫做回调函数。关于回调函数的内容,我们放在后续讲解。
编译部署执行transfer
方法后,我们会发现,账户中的钱已经转到合约中了。乍一看,和我们上述的2.2.1转账有点类似呢?但他们的不同点在哪里呢?下面我们来分析下。得,别分析了,就是一样的。
到这里,我们关于转账的介绍就结束了,不过还有这里大家肯定还有一些疑惑,关于msg.value
怎么来的?我们留在下节介绍。