区块链7-智能合约编程语言-solidity

Solidity语言详解

1.文件结构

2.数据结构

3.错误处理

 

11.参数

12.控制结构

13.可见性

14.函数

 

1.1合约文件结构

1.1.1版权申明

1.1.2import

1.1.3合约 

1.1.3.1状态变量 

1.1.3.2函数

1.1.3.3结构类型

1.1.3.4事件

1.1.3.5函数修改器

1.1.4代码注释

 

语言类型

动态:运行时确定某个变量类型  egg:javascript

静态:声明的时候,编译的时候,指定变量类型或者至少编译时推导出类型,常见的有c,c++,java

solidity静态

值类型 重点booleans integers string address

引用类型

 

布尔类型

取值 true/false

运算符! && || == !=

 

 

整型

int/unit

关键字unit8到unit256(以8步进)

运算符

-比较运算符

-位运算符&,|,^,~

算术运算

 

常量(字面量) 

有理数和整型常量

字符串常量

十六进制常量

地址常量

 

地址类型

address:表示一个账户地址(20字节)

成员 属性:balance余额 函数:transfer()用于转移以太币

地址常量

地址合法性检查

 

引用类型

数据位置 memory内存,storage永久

数组

-T[k]:元素类型为T,固定长度为k的数组

-T[]:数组类型为T,长度动态调整

-bytes string:是一种特殊的数组

-string 可转为bytes,bytes类似byte[]

数组成员:属性:length 函数:push()

 

结构体

struct

映射(Mappings)

mapping(address=>uint)  public balances;

 

全局变量和函数

-有关区块和交易!

msg.sender(address)获取交易发送者地址

msg.value(uint)当前交易所附带的以太币,单位是位

block.coinbase(address)当前块的地址

block.difficulty(uint)当前块的难度

block.number(uint)当前区块的块号

block.timestamp(uint)当前块时间戳

now(uint)当前区块的时间戳,实际上是timestamp的别名

tx.gasprice(uint)当前交易的价格

-有关错误处理!

什么是错误处理 指在程序发生错误时的处理方式

处理方式 回退状态 assert (通常检查函数内部的错误,消耗所有提供的gas,egg:下标越界,整数/0,assert方法调用参数时false,是assert类型异常)。require(检查输入的变量或者合约的状态变量是否满足条件,通常时外部                                 合约的条件,不会消耗提供的gas,egg:gas不足,没有匹配到正常的函数等等)

把区块链当作分布式事务性数据库:数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的                                                           全部数据库操作组成。[1]

-有关数字及加密功能

-有关地址和合约

 

函数参数

-输入参数

-输出参数  函数的返回值

-命名参数  {a: 1, b: 3}

-参数解构  用在函数式编程比较多

 

控制结构

if,else,while,do,for,break结束本次循环,continue下一步,return,?:

没有switch goto

 

可见性

-public 函数默认可见性,公开函数是合约接口的一部分,可以通过内部,或者消息调用。对于public类型的状态变量,会自动创建一个访问器(可以理解为get函数) 

-private 私有的函数和状态变量仅在 当前合约 中可以访问,在继承的合约内不可访问(不能修改,可以看到)

-external 外部函数是合同接口的一部分,只能使用 消息调用

-internal 状态变量默认的可见性,函数和状态只能通过内部访问。如在 当前合约 或 继承合约 里调用

表达式 this.g(8);和 c.g(2)(这里的 c 是一个合约实例)是外部调用函数的方式,它会发起一个消息调用

public和external区别 public多了一个调用方式,如果我们有一个函数,它只接收外部调用的话,使用external而不是public,因为external消耗gas更少

方式=内部+消息调用

内部=当前合约+继承合约

消息调用=this+c.g()

public为方式

private为方式->内部->当前合约

external为方式->消息调用

internal为方式->内部

 

函数

-构造函数

-视图函数(constant/view)(不会修改 状态变量)(不能触发事件-认为是修改状态变量)(不能创建合约)

-纯函数(pure)(既不会读也不会修改 状态变量)

-回退函数(无名函数,一个智能合约需要接受以太币的时候,我们就需要实现这样的回退函数,它是一个被动调用的函数)

 

pragma solidity ^0.4.0;

import "solidity_for_import.sol";

// This is a test Contract

contract Test {
    uint a;
    bool boola = true;
    bool boolb = false;
    int256 c = 20; // int256==int
    int256 d = 30;

    function testadd() public constant returns (int) {
        if (b > c){
            return b + c
        } else if (b == c){
            return b * c
        } else {
            return b >> 2
        }
    }

    function testLiterals() public constant returns (int) {
        return 1231321321.0 * 1.5e10;
    }

    function testStringLiterals() public constant returns (string) {
        return "abc";
    }

    function testHexLiterals() public constant returns (bytes2, bytes1, bytes1) {
        bytes2 a = hex"abcd"
        return (a, a[0], a[1];)
    }

    function testbool1() returns (bool) {
        return boola && boolb;
    }

    function testbool2() returns (bool) {
        return boola || boolb;
    }

    function testbool3() returns (bool) {
        return !boola
    }
 
    function setA(unit x) public {
        a = x
        emit Set_A(X);
    }

    event Set_A(uint a);

    struct Position {
        int lat:
        int lng
    }

    address public owerAddr;

    // 修改函数的行为 函数修改器
    modifier owner () {
        require(msg.sender == owerAddr);
        _;
    }

    function mine() public owner {
        a += 1;
    }
}

solidity_for_import.sol

pragma solidity ^0.4.0;

contract ForImport {
    
}
pragma solidity ^0.4.0;

contract ArrayTest{
    uint[] public u = [1, 2, 3];

    string s = "abcdefg;

    function h() public returns (uint) {
        u.push(4);
        return u.length;
    }

    function f() public view returns (byte) {
        return bytes(s)[1];
    }

    function new(uint len) constant public returns (uint) {
        uint[] memory a = new uint[] (len);
        bytes memory b = new bytes(len);
        a[6] = 8;
        // 错a.length = 100;
        // 对u.length = 100;
        g([unit(1), 2, 3]);
        return a.length;
    }

    function g(uint[3] _data) public constant {

    } 

    struct Funder {
        address addr;
        uint amount;
    }

    Funder funder;

    function newFunder() public {
        funder = Funder({addr: msg.sender, amount: 10});
    }

    mapping(address=>uint) public balances;

    function updateBalance(uiny newBalance) public {
        balances[msg.sender] = newBalance
    }

    function testApi1() public constant returns (address) {
        return msg.sender;
    }

    constructor() payable {

    }

    function testApi2() public payable returns (uint) {
        return msg.value;
    }

    function testApi3() public constant returns (address) {
        return block.coinbase;
    }

    function testApi4() public constant returns (uint) {
        return block.difficulty;
    }

    function testApi5() public constant returns (uint) {
        return block.number;
    }
}
pragma solidity ^0.4.0;

contract Test{
    function simpleIntput(uint a, uint b) public constant returns (uint sum, uint mul) {
        sum = a + b
        mul = a * b
    }

    function testSimpleInput() public constant returns (uint sum, uint mul) {
        //sum = simpleIntput({a: 1, b: 3}); // 等于sum = simpleIntput({b: 1, a: 3});
        (sum, mul) = simpleIntput({ b : 3, a : 1});
    }

    function f() public constant returns (uint, bool, uint) {
        return (7, true, 2)
    }

    function g() public {
        var (x, y, z) = f()

        (, y, z) = f()
        (x, ) = (1, 2);

        // 交换x和z的值
        (x, z) = (z, x)
    }
}
pragma solidity ^0.4.0;

contract Test{
    uint public data; // 生成访问器,可以理解为get函数
    
    function f(uint a) privare returns (uint b) {
        return a + 1;
    }

    function setData(uint a) internal {
        data = a;
    }

    function exSetData(uint a) external {
        data = a;
    }
    
    function testsetData() public {
        setData(1);
        this.exSetData(1); // 转化为消息的调用
    }

    function abc() public(){
        testsetData();
        this.testsetData();
    }
}

contract Test2 is Test {
    function setData(uint a) internal {
        data = a
    }
}

contract D {
    function readData() public {
        Test test = new Test();
        test.setData(1);//x
        test.exSetData(1);//y
        tet.testsetData();//y
    }
}
pragma solidity ^0.4.0;

contract Test{
    uint internal data;

    // 构造函数
    constructor () public {
        data = a;
    }

    event EVENTA(uint a);

    // 视图函数
    function testView() public constant returns (uint) {    // constant是view别名
        // data = 1       x   不能修改状态变量
        // emit EVENTA(1); x  不能出发事件
        return data;
    }

    // 纯函数
    function f() public pure returns (uint) {
        // return 1 * 2 + data; x 不能读取
        // this.balance; x
        // msg.value; x
        return 1 * 2 + 3;
    }

    // 回退函数,一个函数只有一个回退函数,多个的话会出错
    // 调用函数,
    // 1.给这个合约发送以太币 
    // 2.我们在给我们调用的这样合约的函数,但是这个合约函数实际上并不存在,这个时候也会被动的调用这个回退函数
    //   就是我们在调用一个合约,没有匹配到对应的函数的时候,它就会调用回退函数
    // 需要注意的是,这样一个回退函数,我们可以在里面加一些实现,比如触发了一个事件等等,需要注意的是,里面的实现应该尽量简单
    // 否则,在给这个合约转账的时候,发送者容易因为gas不足而交易失败
    function () public payable {
        emit EVENTA(1);
    }
}

contract Caller {
    // 合约想接受以太币,必须有回退函数 并且 必须带有payable
    function callTest(Test test) public {
        test.send(1 ether);
    }
}
pragma solidity ^0.4.0;

contract AddrTest {

    // 余额
    function deposit() public payable {

    }

    // 地址
    function getBalance() public constant returns (uint) {
        return this.balance;
    }

    // 转账
    function transferEther(address towho) public {
        towho.transfer(10);
    }
}
pragma solidity ^0.4.0


contract Sharer {
    function sendHalf(address addr) public payable returns (uint balance) {
        require(msg.value % 2 == 0);
        uint balanceBeforeTranfer = this.balance

        addr.transfer(msg.value / 2 + 1)

        assert(this.balance == balanceBeforeTranfer - msg.value / 2)

        return this.balance;
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以太坊智能合约是基于以太坊区块链技术的智能合约,可以实现自动化的合同执行和全球范围内的去中心化应用程序开发。在以太坊上编写智能合约需要使用Solidity语言。 以下是以太坊智能合约编程的菜鸟教程: 1. 安装Solidity编译器 Solidity是以太坊上最常用的智能合约编程语言,需要安装Solidity编译器才能编写和部署Solidity智能合约。可以从官方网站或GitHub上下载Solidity编译器。 2. 编写智能合约 使用Solidity编写智能合约需要掌握Solidity语言的语法和关键字。可以在Remix集成开发环境中编写Solidity智能合约,也可以在本地使用Solidity编译器进行编写。 以下是一个简单的Solidity智能合约示例: ``` pragma solidity ^0.8.0; contract MyContract { uint256 public myNumber; function setNumber(uint256 _number) public { myNumber = _number; } } ``` 这个智能合约定义了一个名为MyContract的合约,包含一个名为myNumber的公共变量和一个名为setNumber的公共函数。setNumber函数将传入的参数设置为myNumber的值。 3. 编译和部署智能合约 编写完智能合约后,需要使用Solidity编译器将其编译成字节码。可以使用Remix集成开发环境或本地Solidity编译器进行编译。 部署智能合约需要连接以太坊网络,并使用以太坊钱包或其他工具进行部署。部署智能合约时需要支付以太币作为燃料费。 4. 调用智能合约方法 部署智能合约后,可以使用以太坊钱包或其他工具调用智能合约中的方法。使用Solidity编写的智能合约方法可以通过Web3.js或其他以太坊API进行调用。 以上是以太坊智能合约编程的基本流程,希望能对初学者有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百战成王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值