Uniswap交易所开发稳定版丨Uniswap交易所系统开发(开发模板)
基于区块链的去中心化、不可篡改、共识算法、匿名性与跨平台等特性,区块链+游戏将带来如下变革: 1.去中心化运营 游戏中的各系统设置使用智能合约技术开发,游戏数据存储在区块链上,不依赖中心化服务器; 2.数据可信任 结合区块链技术开发游戏,重要的数据存储在区块链上,游戏运营方无法随意篡改与删除游戏数据,稀有道具内容、数量及抽签概率等算法完全公开,使得游戏数据透明化,可信任化,成为一个可信任的去中心化游戏应用;编辑智能合约的结构 合约就像一个类(class),其中包含: 状态变量(state variable) 函数(function) 函数修改器(function modifier) 事件(event) 结构(structure) 枚举(enum) 示例:contract Sample { //状态变量 uint256 data; address owner; //定义事件 event logData(uint256 dataToLog); //函数修改器 modifier onlyOwner(){ if(msg.sender!=owner)throw; } //构造器,名字与合约名一致 function Sample(uint256 initData,address initOwner){ data=initData; owner=initOwner; } //函数 function getData()returns(uint256 returnedData){ return data; } function setData()returns(uint256 newData)onlyOwner{ logData(newData); data=newData; } } 代码注释: contract关键字:用于声明一个合约 data和owner:是两个状态变量。data包含一些数据,owner包含所有者的以太坊钱包地址,即部署合约者的以太坊地址 event logData定义事件logData,用于通知客户端:一旦data发生变化,将触发这个事件。所有事件都保存在区块链中。 函数修改器:onlyOwner。修改器用于在执行一个函数之前自动检测文件。这里的修改器用于检测合约所有者是否在调用函数。如果没有,则会抛出异常。 合约函数构造器constructor:在部署合约时,构造器用于初始化状态变量。 function,getData()用于得到data状态变量的值,setData()用于改变data的值。 基本类型 除了数组类型、字符串类型、结构类型、枚举类型和map类型外, 其他类型均称为基本类型。 无符号型:例如uint8,uint16,uint24,…,uint256分别用于存储无符号的8位,16 位,24位,…,256位整数 有符号型:例如,int8,int16,…,int256分别用于存储8位,16位,24位,…,256位整数 address类型:用于存储以太坊地址,用16进制表示。address类型有两个属性:balance和send。balance用于检测地址余额,send用于向地址发送以太币。send方法拿出需要转账那 些数量的wei,并根据转账是否成功返回true或者false。 注意: uint和int是uint256和int256的别名。 如果一个数字超过256位,则使用256位数据类型存储该数字的近似值。 数组:Solidity支持generic和byte两种数组类型。 数组有length属性,用于发现数组的长度。 注意:不可以在内存中改变数组大小,也不可以改变非动态数组大小。 字符串类型 有两种方法创建字符串:使用bytes和string。 bytes用于创建原始字符串,而string用于创建UTF-8字符串 示例: contract sample{ string myString=””;//string bytes myRawString; function sample(string initString,bytes rawStringInit){ myString=initString; string storage myString2=myString; string memory myString3=”ABCDE”; myString3=”imaginecode”; myRawString=rawStringInit; myRawString.length++; } } 结构类型struct 示例 contract sample{ struct myStruct{ bool myBool; string myString; } myStruct s1; myStruct s2=myStruct{true,””}; function sample(bool initBool,string initString){ s1=myStruct(initBool,initString); myStruct memory s3=myStruct(initBool,initString); } } 注意:函数参数不可以是结构类型,且函数不可以返回结构类型。 枚举类型enum 示例 contract sample{ enum OS{OSX,Linux,Unix,windows} OS choice; function sample(OS chosen){ choice=chosen; } function setLinux(){ choice=OS.Linux; } function getChoice return(OS chosenOS){ return choice; } } mapping类型 mapping类型只可以存在于storage中,不存在于memory中,因此它们是作为状态变量声明的。 mapping类型包含key/value对,不是实际存储key,而是存储key的keccak256哈希,用于查询value。 mapping不可以被分配给另一个mapping。 constract sample{ mapping(int=>string)myMap; function sample(){ myMap[key]=value; mapping(int=>string)myMap2=myMap; } } 注意:如果想访问mapping中不存在的key,返回的value为0。 delete操作符 可用于操作任何类型的变量。 对动态数组使用delete操作符,则删除所有元素,其长度变为0。 对静态数组使用delete操作符,则重置所有索引 对map类型使用delete操作符,什么都不会发生,但是,对map类型的一个键使用delete操作符,则会删除与该键相关的值 示例 contract sample{ struct Struct{ mapping(int=>int)myMap; int myNumber; } int[]myArray; Struct myStruct; function sample(int key,int value,int number,int[]array){ myStruct=Struct(number); myStruct=Struct(number); myStruct.myMap[key]=value;//对某个键赋值 myArray=array; } function reset(){ delete myArray;//myArray数组长度为0 delete myStruct;//myNumber为0,myMap不变 } function deleteKey(int key){ delete myStruct.myMap[key];//删除myMap中的某个键的值 } } 基本类型之间的转换 隐式转换:常用。通常来说,如果没有语义信息丢失,值和类型之间可以进行隐式转换:uint8可转换为uint16,int128可转换为int256,但是int8不可转换为uint256(因为uint256不能存储,例如-1) Solidity也支持显式转换,如果编译器不允许在两种数据类型之间隐式转换,则可以进行显式转换。建议尽量避免显式转换,因为可能返回难以预料的结果。 示例: uint32 a=0x12345678; uint16 b=uint16(a);//b=0x5678,将uint32类型显式转换为uint16,也就是说,把较大类型转换为较小类型,因此高位被截掉了 var 使用关键字var声明的变量,其变量类型根据分配给它的第一个值来动态确定。一旦分配了值,类型就固定了,所以如果给它指定另一个类型,将引起类型转换。 int256 x=12; var y=x;//此时y的类型是int256 uint256 z=9; y=z;//此时,报出异常,因为uint256不能转换为int256类型 但要注意的是: 在定义数组array和map时不能使用var。var也不能用于定义函数参数和状态变量 控制结构 if-else while for breakcontinue return ?: 等等 //结构上和其他语法没有什么差异 contract sample{ int a=12; int[]b; function sample(){ if(a==12){} else if(a==34){} else{} var temp=10; while(temp<20) { if(temp==17){break;} else{continue;} } temp++; } for(var m=0;m<b.length;m++){ } } 用new操作符创建合约 一个合约可以使用new关键字来创建一个新合约。 例如: contract sample1{ int a; function assign(int b){ a=b; } } contract sample2{ function sample2(){ sample1 s=new sample1();//注意写法 s.assign(12); } } 异常 异常的抛出分为自动和手动。 若你想手动抛出异常,可以使用throw手动抛出。 注意,异常抛出后,会撤销对状态和余额的所有改变。 contract sample{ function myFunction(){ throw; } } 函数调用 内部函数调用:一个函数在同一个合约中调用另一个函数 外部函数调用:一个函数调用另一个合约的函数。
发表回复