以太坊智能合约简介(Solidity)

简介: 本文略过了冗杂介绍,直接下沉到代码示例。本文中包含一个存储实例和生成极简单 subcurrency 的实例

本文会通过两个示例来简单介绍智能合约

示例一:存储(Storage)

下面这段代码实现了一个uint值的存储。

pragma solidity ^0.4.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public constant returns (uint) {
        return storedData;
    }
}

在某种意义上,Solidity合约就是在以太坊区块链中特定地址内的一组代码(合约的函数)和数据(合约的state)的集合。

uint storedData;

这一行声明了一个uint(256bit的无符号整数)类型的state变量:storedData。你可以认为storedData是数据库中的一个存储单元,它可以被通过执行数据库管理代码的方式查询和修改。在以太坊中只有合约的所有者能这样做。示例代码中,setget函数可以被用于修改或检索变量的值

获取state对象,不需要像其他语言那样加this.前缀

由于此合约仅存储了一个完全公开的数字,所以它的发布是无法被阻止的。但任何人都可以通过以另一参数调用set来覆盖你刚刚保存的数字(但你写过的那个数字仍会被保存在区块链历史中)。稍后,你将看到如何设置限制以确保只有你自己可以修改这个变量的值

注意,所有标识符(如合约名,变量名,函数名等)只能使用ascii字符集。UTF-8编码的数据可以存储在字符串变量中

使用与其他字符相似的Unicode字符时需要保持小心

 

示例二:子货币Subcurrency

下面的合约将会实现一种最简单的加密货币。这里定义的货币可以凭空产生,但只有创建合约的人才有能力凭空生成货币(实现一个不同的发币计划是件微不足道的小事)。 此外,任何人都可以互相发送货币而不需要使用用户名和密码进行注册——进行所有的一切,只需要一个以太坊密钥对。

 
 
pragma solidity ^0.4.21;

contract Coin {
    // The keyword "public" makes those variables
    // readable from outside.
    address public minter;
    mapping (address => uint) public balances;

    // Events allow light clients to react on
    // changes efficiently.
    event Sent(address from, address to, uint amount);

    // This is the constructor whose code is
    // run only when the contract is created.
    function Coin() public {
        minter = msg.sender;
    }

    function mint(address receiver, uint amount) public {
        if (msg.sender != minter) return;
        balances[receiver] += amount;
    }

    function send(address receiver, uint amount) public {
        if (balances[msg.sender] < amount) return;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Sent(msg.sender, receiver, amount);
    }
}

这段合约带来了一些新的概念,以下将一一介绍

 

address public minter;声明了一个address类型的state变量,这个变量是所有人都可以读取的。address类型是一个不允许进行任何算术操作的160位值。它很适合被用来存储合约地址或属于外部个人的密钥对。关键字public会自动生成一个允许你从合约外部获取一个state变量当前值的函数。若没有这个关键字,其他合约将无法获取到这个变量。由编译器生成的代码和下面这行代码大致相同

function minter() returns (address) { return minter; }

(直接加上这句会导致编译器报错,因为此函数和state变量重名)

下一行:mapping (address => uint) public balances;

这句话创建了一个数据类型更加复杂的公共state变量——一个从地址到无符号整型的映射。此处的映射可以被看做一个虚拟初始化了的hash表,以便每个可能的密钥存在,并映射到一个字节表示全是0的值上(这个比喻不太合理,因为包含一个有映射的所有键的列表是不可能的,包含所有值也是不可能的)。因此要么保存添加到映射中的内容,要么在不需要这种内容的部分使用它(就像这句)。由public关键字创建的getter函数【注1】在这种情况下更加复杂一些。看起来大概是这样的:

function balances(address _account) public view returns (uint) {
    return balances[_account];
}

用这个函数可以轻松查询一个账户的余额

 

event Sent(address from, address to, uint amount);

这行声明了一个所谓的“event(事件)”,它被最后的send函数发出。包括服务端应用在内的用户接口可以以较低的成本监听这些被发送到区块链上的事件。一旦事件被发送,监听者就会获取到fromtoamount参数,以便监听者跟踪交易。为监听这一事件,我们会使用

 
 
Coin.Sent().watch({}, '', function(error, result) {
    if (!error) {
        console.log("Coin transfer: " + result.args.amount +
            " coins were sent from " + result.args.from +
            " to " + result.args.to + ".");
        console.log("Balances now:\n" +
            "Sender: " + Coin.balances.call(result.args.from) +
            "Receiver: " + Coin.balances.call(result.args.to));
    }
})

注意,自动生成的函数balance是怎样从用户接口调用的

 

Coin这个特殊的函数时在创建合约时调用的构造器,他不能在合约构造完成后再被调用。它永久存储了合约创建者的地址:msg(和txblock一起)。msg是一个神奇的全局变量,包含一些允许连接到区块链的属性。msg.sender永远是当前的(外部)函数调用所来自的地址。

 

这个合约中的函数可以被用户和其他合约调用,如mintsendmint只能被合约创建者进行有效的调用。而send可以被任何已经持有一些这种币的人调用来向他人进行转账。注意如果你用这个合约发送币到其他地址,你在区块链浏览器上浏览目标地址时并不会看到任何效果产生,因为你发送了币并改变余额的事实只存储于这个特定的货币合约的数据存储中。因为有了事件的使用,创建一个用于跟踪你自己的货币的交易和余额的“区块链浏览器”变得比较简单。

 

 

【注1】:getter函数时编译器为所有public的state变量自动创建的,它会返回一个uint类型的名为“data”的state变量值。状态变量的初始化可以在声明时完成。

 


相关文章
|
5月前
|
IDE 编译器 区块链
基于 Solidity 的智能合约详解
基于 Solidity 的智能合约详解
61 2
|
存储 前端开发 JavaScript
区块链智能合约编程语言 Solidity
上文介绍了[区块链生态发展](https://wangbinguang.blog.csdn.net/article/details/131440404),我们知道以太坊的到来可以使开发人员基于区块链开发DApp,本文介绍 Solidity 编程语言的使用,然后基于 Solidity 编写一个简单的智能合约。
125 1
|
JavaScript 前端开发 区块链
【区块链Solidity】智能合约与Solidity介绍
【区块链Solidity】智能合约与Solidity介绍
142 0
|
存储 区块链 数据库
Solidity开发智能合约
一个简单的智能合约 在Solidity中,一个合约由一组代码(合约的函数)和数据(合约的状态)组成。合约位于以太坊区块链上的一个特殊地址。
1518 0
|
存储 机器学习/深度学习 人工智能
智能合约简介
智能合约远胜于传统交易流程,因为它们有可能实现自动化,在某些情况下,甚至可以完全取代整个行业。同时,智能合约使交易更加公平、透明和安全。但是,除了实现自动化和改进单一的交易过程之外,智能合约还能发挥更大的作用。
464 0
智能合约简介
|
存储 JavaScript 前端开发
【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言
目录 注意事项 编译器选择 一些说明 1. 变量 1.1 状态变量 1.2 局部变量 2. 数据类型 2.1 值类型 2.1.1 布尔类型(Booleans): 2.1.2 整型(Integers): 2.1.3 定长浮点型(Fixed Point Numbers): 2.1.4 定长字节数组(Fixed-size byte arrays) 2.1.5 有理数和整型常量(Rational and Integer Literals) 2.1.6 枚举(Enums) 2.1.7 函数类型(Function Types) 修饰符 函数定义 函数返回值 构造函数 2.1.8 地址类型(Address)
417 0
【智能合约】Solidity 基础知识 | 以太坊智能合约编程语言
|
存储 Java 区块链
6分钟以太坊实战 - 智能合约与Solidity高级语言(一)
1. 简介 合约是存放在以太坊区块链具有特定地址的代码和数据集合。 合约账户之间可以相互传递消息以实现图灵完备运算。 合约以以太坊特定的二进制字节码通过以太坊虚拟机(EVM)运行于区块链上。目前,合约通常是以Solidity(一门长得很像js的语言)高级语言编写,编译后传到区块链上运行。
9606 0
|
前端开发 JavaScript 区块链
以太坊智能合约开发入门
以太坊合约就是以太坊区块链特定账户地址上的一串代码(functions)和数据(state)。合约账户不仅可以相互间通讯,还可以执行几乎所有的图灵完备计算。以太坊区块链上的合约代码是特定的二进制形式,被称作以太坊虚拟机(EVM)二进制代码。本文以最受欢迎的Solidity为例说明以太坊开发如何入门。
5594 0
|
JSON 区块链 数据格式
如何通过solc编译solidity编写的以太坊智能合约
solc:solidity的编译器 solidity编写的以太坊智能合约可通过命令行编译工具solc来进行编译,成为以太坊虚拟机中的代码。
2342 0