20181116--solidity语言复习

solidity的语言是为了能在以太坊上面部署智能合约
Solidity是一种语法类似JavaScript的高级语言。它被设计成以编译的方式生成以太坊虚拟机代码。在后续内容中你将会发现,使用它很容易创建用于投票、众筹、封闭拍卖、多重签名钱包等等的合约。

智能合约

contract Coin
//声明一个合约叫Coin
 {
//关键字“public”使变量能从合约外部访问。
    address public minter;//一个地址变量叫做 minter address类型的值大小为160 bits,不支持任何算术操作,适用于存储合约的地址或其他人的公私钥,没有public关键字的变量将无法被其他合约访问。
    mapping (address => uint) public balances; //一个映射 mapping  通过address 能得到一个uint的balances的余额 mapping可以被认为是一个哈希表,每一个可能的key对应的value被虚拟的初始化为全0.这个类比不是很严谨,对于一个mapping,无法获取一个包含其所有key或者value的链表。所以我们得自己记着添加了哪些东西到mapping中。更好的方式是维护一个这样的链表,或者使用其他更高级的数据类型。或者只在不受这个缺陷影响的场景中使用mapping

//事件让轻客户端能高效的对变化做出反应。
    event Sent(address from, address to, uint amount);
    //声明一个事件

//这个构造函数的代码仅仅只在合约创建的时候被运行。
    function Coin() {
        minter = msg.sender;
    }
    //声明一个构造函数 Coin 在合约创建的时候被调用
    function mint(address receiver, uint amount) {
        if (msg.sender != minter) return;
        balances[receiver] += amount;
    }
    //mint函数
    function send(address receiver, uint amount) {
        if (balances[msg.sender] < amount) return;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        Sent(msg.sender, receiver, amount);
    }
    //send函数 转账的交易
}

外部账户的地址是由公钥决定的,合约账户的地址是在创建该合约时确定的(这个地址由合约创建者的地址和该地址发出过的交易数量计算得到,地址发出过的交易数量也被称作"nonce")

安装solidity
solidity实例
Voting投票

contract Ballot
{
    struct Voter
    //定义了一个结构体类型
    {
        uint weight;//累积的权重
        bool voted;//是否已经进行过投票
        address delegate;//委托投票权
        uint vote;//投票选择的提案索引号
        
    }
    struct Proposal
    {
        bytes32 name;//提案的名字
        uint voteCount;//投票累积的数量
    }
    //最初定义结构体
    
    address public chairperson;//定义了address状态变量,记住address相当于一个地址就行
    mapping(address=>Voter) public Voters;//mapping相当于一个数组又相当于一个函数,给address与Voter进行了绑定
    Proposal[] public proposals;//声明一个proposal的数组叫做proposals,智能合约中的数组起名相当于想要的数组数+s形成该变量
    //的数组
    //定义了状态变量
    
    function Ballot(bytes32 proposalName){//构造函数,需要传入bytes32位的合约名字
        chairperson = msg.sender;//合约的调用者就是 msg.sender
        voters[chairperson].weight=1;
        //对提供的每一个提案的名称,创建一个新的提案
        //将对象添加到数组末尾
        for(uint i = 0;i<proposalName.length;i++){
            proposals.push(Proposal({
                name:proposalName[i],
                voteCount:0
            }));
        }
    }
    function giveRightToVote(address voter){//需要给一个地址,才能调用这个函数,相当于赋予其投票权力
        if(msg.sender!=chairperson||voters[voter].voted){
            throw;
            //throw会终止和撤销所有的状态和以太改变
            //如果函数调用无效,这通常是一个好的选择
            //但是注意,这会消耗提供的gas
            voters[voter].weigt=1;
        }
    }
    function delegate(address to){
        //指定引用
        Voter sender = voters[msg.sender];
        if(sender.voted)
            throw;
        while(voters[to].delegate!=address(0)&&voters[to].delegate!=msg.sender)
            to=voters[to].delegate;
        if(to==msg.sender)
            throw;
        //因为sender是一个引用,
        //这里实际修改了voters[msg.sender].voted
        sender.voted=true;
        sender.delegate=to;
        Voter delegate =voters[to];
        if(delegate.voted){
            proposals[delegate.vote].voteCount+=sender.weight;
        else
            delegate.weight +=sender.weight;
        }
    }
    function vote(uint proposal){//进行投票,选取你想要去的项目进行投票
        Voter sender =voters[msg.sender];//进行引用sender是当前投票的voter
        if(sender.voted)throw
        sender.voted=true;
        sender.vote=proposal;
        //如果proposal索引超出了给定的提案数组范围
        //将会自动抛出异常,并撤销所有的改变
        proposals[proposal].voteCount+=sender.weight;
    }
    function winningProposal()constant return(uint winningProposal){
        uint winningVoteCount = 0;
        for(uint =0 ;p<proposals.length;p++){
            if(proposals[p].voteCount>winningVoteCount){
                winningVoteCount =proposals[p].voteCount;
                winningProposal=p;
            }
        }
    }
}

源文件的布局
Solidity支持import语句,非常类似JavaScript(ES6),虽然Solidity不知道“缺省导出”的概念
在全局的层次上,你可以使用下列形式使用import语句

import "filename"; 

合约的结构
Solidity的合约和面向对象语言中的类的定义相似。每个合约包括了 状态变量,函数,函数修饰符,事件,结构类型 和枚举类型。另外,合约也可以从其他合约中继承 。

状态变量是在合约存贮器中永久存贮的值

函数是合约中可执行单位的代码

函数修饰符可以在声明的方式中补充函数的语义

事件是和EVM(以太虚拟机)日志设施的方便的接口

结构是一组用户定义的变量

枚举是用来创建一个特定值的集合的类型
类型
solidity是一种静态语言,类似于脚本语言,意思是每个变量(声明和本地)在编译时刻都要定义
布尔类型:只有真与假
还有操作符: !(非) &&(逻辑与) ||(逻辑或) ==(相等) !=(不等)
操作符||和&&可以应用常规短路规则
整形
int和uint:是有符号和无符号的整数,关键字uint8刀uint256步长(8到256位的无符号整数)
uint和int 分别是uint256和int256 的别名
地址:address 20字节(一个ethereum地址),地址的类型也可以有成员
账户余额balance和发送send
字符串常量:bytes 或者是String
枚举是一种solidity中的创建一个用户定义的类型。枚举类型中的枚举值可显示转换,但是从整数类型隐式转换是不允许的
数组:数组是可以在编译时固定大小的,也可以是动态的。对于存储器数组来说,成员类型可以是任意的(也可以是其他数组,映射或结构)。对于内存数组来说 ,成员类型不能是一个映射;如果是公开可见的函数参数,成员类型是必须是ABI类型的。
length是长度,push是方法与es6一样
结构体:struct
映射:映射类型被声明为 mapping _KeyType => _ValueType, _KeyType可以是除了映射以外的其他任何类型,_ValueType可以是任何类型,包括映射。

块和交易属性
block.coinbase (address): :当前块的矿工的地址
block.difficulty (uint):当前块的难度系数
block.gaslimit (uint):当前块汽油限量
block.number (uint):当前块编号
block.blockhash (function(uint) returns (bytes32)):指定块的哈希值——最新的256个块的哈希值
block.timestamp (uint):当前块的时间戳
msg.data (bytes):完整的calldata
msg.gas (uint):剩余的汽油
msg.sender (address):消息的发送方(当前调用)
msg.sig (bytes4):calldata的前四个字节(即函数标识符)
msg.value (uint):所发送的消息中wei的数量
now (uint):当前块时间戳(block.timestamp的别名)
tx.gasprice (uint):交易的汽油价格
tx.origin (address):交易发送方(完整的调用链)

合约
Solidity里的合约是面向对象语言里的类。它们持久存放在状态变量和函数中,(在里面)可以修改这些变量。在不同的合约(实例)中调用一个函数(的过程),(实际上)是在EVM(Ether虚拟机)中完成一次调用,并且完成(一次)上下文切换,(此时)状态变量是不可访问的。

猜你喜欢

转载自blog.csdn.net/qq_36344771/article/details/84145929
今日推荐