您的位置:首页 > 其它

以太坊智能合约学习笔记(一)

2018-04-10 10:16 387 查看
什么是智能合约(Smart Contract):最简单的理解,我们所说的智能合约就是区块链上自动运行的一段程序。而基于Ethereum的智能合约就是我们接下来所要学的以太坊智能合约。这里,在我们的Smart Contract中,具体的代码经过solidity编写后,发布到区块链上。而以太坊的智能合约也可以理解为一个特殊的交易(包括可执行的代码),被发送出去后会被矿工打包记录在某一区块中。在这一系列笔记中,我们将以实例为基础,讲解智能合约开发的流程。首先我们将一起建立一个基础的单员工薪酬系统,并在后续一步步进行完善。源码地址:https://github.com/Chlover/Team-J/blob/master/Lesson-1/orgin/payroll.sol版本声明:
//声明程序版本
pragma solidity ^0.4.14
因为Solidity大多是开源的程序,所以要在程序的最开始声明程序版本,方便社区合作。
^
表示向上兼容,
^0.4.14
表示
solidity
的版本在
0.4.14~0.5.0(不包含0.5.0)
的版本都可以对上面的合约代码进行编译,
0.4.18
,
0.4.20
等等可以用来修复前面solidity
存在的一些bug
。声明Contract:
// 声明一个Contract
contract Payroll {

}
Solidity是一门面向对象编程的语言,语法较为贴近JavaScript。其中合同的声明就类似于声明一个Class。状态变量声明:
// 声明一个Contract
contract Payroll {
    address Owner;
    uint salary;
    address employee;
    uint lastPayday;
 }
变量初始值均为0状态,address变量初始化即为0x0。另外注意在solidity源代码中,地址就是一串十六进制数,不需要加双引号,但是在Remix的对话界面中输入address时,一定要加双引号,不然会报错。这是因remix传入是是json格式,对于不加双引号的值会作为为int处理,加了引号才算bignumber。这里的int指的是js的int,地址明显超过范围,类似的输入一个超大int256数也要加引号。构造函数:
function Payroll() {
    owner = msg.sender;
}
函数名和合约名相同时,此函数是合约的构造函数,当合约对象创建时,会先调用构造函数对相关数据进行初始化处理。此处相当于在合约创建时就直接将合约的创建者设为owner,后续将保证只有owner可以更新雇员信息。具体功能的函数实现:
function addFund() payable returns (uint) {
    return this.balance;
}
用addfund函数向合约里加钱。值得注意的是
payable
关键字,当函数有
payable
关键字的时候,就表明即可接受ether,并会把ether存在当前合约。http://solidity.readthedocs.io/en/develop/frequently-asked-questions.html?highlight=payable
returns
后面加函数返回值的类型。接下来这一部分我们要实现的是更新雇员信息的功能:
function updateEmployee(address e, uint s) {
    require(msg.sender == owner);
   
    if (employee != 0x0) {
        uint payment = salary * (now - lastPayday) / payDuration;
        employee.transfer(payment);
    }
    employee = e;
    salary = s * 1 ether;
    lastPayday = now;
 }
首先可以发现新出现
require
语句。后面我们还将见到
assert
,这里我们放在一起讲解:
require
assert
都是用于处理error的,二者可以用于判断某一条件,若条件不被满足则
throw exception
。其中,
require
主要用于检查输入值,而
assert
则主要用于检查
internal
error
。Theassert function should only be used to test for internal errors, and to check invariants.Therequire function should be used to ensure valid conditions, such as inputs, or contract state variables are met, or to validate return values from calls to external contracts.https://solidity.readthedocs.io/en/develop/control-structures.html#error-handling-assert-require-revert-and-exceptions另外,触发
assert
会消耗所有的gas,而触发
require
则会把剩余的gas返还。
assert(false)
 compilesto 
0xfe
,which is an invalid opcode, using up all remaining gas, and reverting all changes.
require(false)
 compilesto 
0xfd
 whichis the 
REVERT
 opcode,meaning it will refund the remaining gas.https://ethereum.stackexchange.com/questions/15166/difference-between-require-and-assert-and-the-difference-between-revert-and-thro中间我们略过一下简单的函数不讲,直接进行最后getPaid函数的说明:
function getPaid() {    require(msg.sender == employee);       uint nextPayday = lastPayday + payDuration;    assert(nextPayday < now);    lastPayDay = nextPayday;    employee.transfer(salary); }
这里我们就应用了上面提到的
require
assert
,这里的
require
要求调用getPaid也就是领取工资的人一定要是雇员。对于
employee.transfer(salary)
和前面我就已经见到的
msg
,我们将在下一篇文章中一起总结。接下来,我们将在https://remix.ethereum.org测试我们写的智能合约首先,我们现在的合约的environment是JavaScript VM,也就是没有真正部署上链的,在后面我们会讲到部署方法,但是最开始的阶段,我们的合约就在JavaScript VM上进行测试。选择以后,remix会自动帮我们生成一些地址,自己也可已经添加,供我们测试使用。在Settings中我们可以选择solidity版本,由于是向上兼容的,我们只要选择高于0.4.14的版本即可,系统会自动为我们compile,没有报错的话就可以点击Create按钮了。我们会注意到右上角的Value有一个单位
wei
这是solidity里的最小单位,我们比较常用的是
ether
1 ether = 10^18 wei
。这时候我们在Value填入我们想add的数值,并调用addFund函数就可以将该数量金额的eth转入合约。切记,在测试updateEmployee和getPaid函数时,要把右上角的Account换成相应的owner或employee地址,这样才能满足
require(msg.sender == 相应地址)
。到目前为止,我们就跟着流程把一个简单的单员工薪酬系统的合约运行了起来,对Solidity也有了大体的了解,在下一篇文章中,我们将对在Solidity的一些基础知识、语法进行补充。

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: