本文作者:admin

智能合约多少字节 智能合约怎么写

admin 2023-02-07 136
智能合约多少字节 智能合约怎么写摘要: 本文对智能合约多少字节,智能合约怎么写内容进行了解读,下面就跟随币杠财经网小编一起了解智能合约多少字节,智能合约怎么写。比特币区块里的各个字段含义(先写了个nonce) nonc...

本文对智能合约多少字节,智能合约怎么写内容进行了解读,下面就跟随币杠财经网小编一起了解智能合约多少字节,智能合约怎么写。

比特币区块里的各个字段含义(先写了个nonce)

nonce是个啥意思?根据bitcoin wiki

nonce是一个4-byte大小的区域,nonce的值设定使得该块的hash是以一串0开头的。

对于块数据的一点点改变(比如nonce)都会引起币墨 hash的巨大变化。由于逆向预测hash值相对应的一组bit值(hash原文)是不可行的,在尝试足够多的nonce值且计算每个nonce值相对应的币墨 hash之后可以找到一个满足有指定数量 0 bits (0比特位) 的hash值。而 0 bits的数量值是由difficult设定的。最终产生的hash须得是一个小于当前difficulty值。

因为这个迭代的计算耗费时间和资源,块的出现也就是得到了正确的nonce值,这构成了 proof of work

关于以太坊里的nonce 网上很多解释,很多一上来就是 交易计数器 , 然而却把跟POW有关的丢了吗?事实上以太坊里的nonce有两种意思,一个是proof of work nonce,一个是account nonce。

那智能合约呢?合约也算是Account的一种,那也有nonce吗?

是的,而且合约里面的nonce也差不多,也是一个counter。在智能合约里,nonce的值代表的是该合约创建的合约数量。只有当一个合约创建另一个合约的时候才会增加nonce的值。但是当一个合约调用另一个合约中的method时 nonce的值是不变的。

在以太坊中nonce的值可以这样来获取(其实也就是属于一个账户的交易数量):

但是这个方法只能获取交易once的值。目前是没有内置方法来访问contract中的nonce值的,除了自己定义一个counter来计数...

那好,再来看一下Ethereum 币墨中的nonce:

以太坊和比特币区块链一样,也需要proof of work(计划转移到股份证明也早已在做了)。在比特币区块链中,pow应该是要算出一个符合难度要求的值,通常是以一串0开头的。这个难度一直在变化。可以查看 比特币区块链的POW难度变化 。

011:Ethash算法|《ETH原理与智能合约开发》笔记

待字闺中开发了一门区块链方面的课程:《深入浅出ETH原理与智能合约开发》,马良老师讲授。此文集记录我的学习笔记。

课程共8节课。其中,前四课讲ETH原理,后四课讲智能合约。

第四课分为三部分:

这篇文章是第四课第一部分的学习笔记:Ethash算法。

这节课介绍的是以太坊非常核心的挖矿算法。

在介绍Ethash算法之前,先讲一些背景知识。其实区块链技术主要是解决一个共识的问题,而共识是一个层次很丰富的概念,这里把范畴缩小,只讨论区块链中的共识。

什么是共识?

在区块链中,共识是指哪个节点有记账权。网络中有多个节点,理论上都有记账权,首先面临的问题就是,到底谁来记帐。另一个问题,交易一定是有顺序的,即谁在前,前在后。这样可以解决双花问题。区块链中的共识机制就是解决这两个问题,谁记帐和交易的顺序。

什么是工作量证明算法

为了决定众多节点中谁来记帐,可以有多种方案。其中,工作量证明就让节点去算一个哈希值,满足难度目标值的胜出。这个过程只能通过枚举计算,谁算的快,谁获胜的概率大。收益跟节点的工作量有关,这就是工作量证明算法。

为什么要引入工作量证明算法?

Hash Cash 由Adam Back 在1997年发表,中本聪首次在比特币中应用来解决共识问题。

它最初用来解决垃圾邮件问题。

其主要设计思想是通过暴力搜索,找到一种币墨头部组合(通过调整nonce)使得嵌套的SHA256单向散列值输出小于一个特定的值(Target)。

这个算法是计算密集型算法,一开始从CPU挖矿,转而为GPU,转而为FPGA,转而为ASIC,从而使得算力变得非常集中。

算力集中就会带来一个问题,若有一个矿池的算力达到51%,则它就会有作恶的风险。这是比特币等使用工作量证明算法的系统的弊端。而以太坊则吸取了这个教训,进行了一些改进,诞生了Ethash算法。

Ethash算法吸取了比特币的教训,专门设计了非常不利用计算的模型,它采用了I/O密集的模型,I/O慢,计算再快也没用。这样,对专用集成电路则不是那么有效。

该算法对GPU友好。一是考虑如果只支持CPU,担心易被木马攻击;二是现在的显存都很大。

轻型客户端的算法不适于挖矿,易于验证;快速启动

算法中,主要依赖于Keccake256 。

数据源除了传统的币墨头部,还引入了随机数阵列DAG(有向非循环图)(Vitalik提出)

种子值很小。根据种子值生成缓存值,缓存层的初始值为16M,每个世代增加128K。

在缓存层之下是矿工使用的数据值,数据层的初始值是1G,每个世代增加8M。整个数据层的大小是128Bytes的素数倍。

框架主要分为两个部分,一是DAG的生成,二是用Hashimoto来计算最终的结果。

DAG分为三个层次,种子层,缓存层,数据层。三个层次是逐渐增大的。

种子层很小,依赖上个世代的种子层。

缓存层的第一个数据是根据种子层生成的,后面的根据前面的一个来生成,它是一个串行化的过程。其初始大小是16M,每个世代增加128K。每个元素64字节。

数据层就是要用到的数据,其初始大小1G,现在约2个G,每个元素128字节。数据层的元素依赖缓存层的256个元素。

整个流程是内存密集型。

首先是头部信息和随机数结合在一起,做一个Keccak运算,获得初始的单向散列值Mix[0],128字节。然后,通过另外一个函数,映射到DAG上,获取一个值,再与Mix[0]混合得到Mix[1],如此循环64次,得到Mix[64],128字节。

接下来经过后处理过程,得到 mix final 值,32字节。(这个值在前面两个小节《 009:GHOST协议 》、《 010:搭建测试网络 》都出现过)

再经过计算,得出结果。把它和目标值相比较,小于则挖矿成功。

难度值大,目标值小,就越难(前面需要的 0 越多)。

这个过程也是挖矿难,验证容易。

为防止矿机,mix function函数也有更新过。

难度公式见课件截图。

根据上一个区块的难度,来推算下一个。

从公式看出,难度由三部分组成,首先是上一区块的难度,然后是线性部分,最后是非线性部分。

非线性部分也叫难度炸弹,在过了一个特定的时间节点后,难度是指数上升。如此设计,其背后的目的是,在以太坊的项目周期中,在大都会版本后的下一个版本中,要转换共识,由POW变为POW、POS混合型的协议。基金会的意思可能是使得挖矿变得没意思。

难度曲线图显示,2017年10月,难度有一个大的下降,奖励也由5个变为3个。

本节主要介绍了Ethash算法,不足之处,请批评指正。

以太坊智能合约代码长度限制

限制为最长可达到合约的24KB大小。

以太坊智能合约包含太多函数和代码,将轻易达到合约24KB大小的最大限制,一些合约标准需要许多功能,那对于这些大的合约来说,这是一个大的问题。

以太坊智能合约是一段程序,部署在以太坊上的智能合约,运行在以太坊的虚拟机EVM中,程序可以按照事先约定的某种规则自动执行操作,执行合约的条款。

NFT不同协议标准

“Non-Fungible Tokens”,英文简写为“NFT”。

ERC 是「Ethereum Request for Comments」的缩写,意思是以太坊开发者公开征求意见,希望定义出统一的沟通接口,建立出一套可以遵循的标准, 让以太坊开发者在撰写智能合约时能更为流畅 。

NFT 全称为 non-fungible Token,非同质化通证。NFT 的重要特征在于:每一个 NFT 拥有独特且唯一的标识,两两不可互换,最小单位是 1 且不可分割。(发行 token 时为每一个 token 设置不同的 token ID 进行区别)。

用于处理不可替换资产的一种以太坊代币标准。可替换资产像是货币,它可以被其他任何平等单位替代,但诸如房屋、家具则属不可替换资产,它不能被替代,也不能被分割,这就是 ERC721 规格标准的主要效果。

租用NFT的标准,可以理解为加入租用功能的ERC-721协议。该协议具有排他性,即当一人完成对某一NFT的租赁之后,那么其他用户便无法再去访问或使用该NFT。

允许用户在一笔交易过程中批量转移/交易多个NFT,并且转移/交易的手续费会更便宜。用户能够通过对包含价格、交易到期日期和签名等信息进行加密签名来下单。

委托非同质化通证(DNFT),将物理资产附加到数字通证需要的不仅仅是验证通证的方法,它“还要求在物质主权范围内具有法律效力。”也就是说,必须有一个围绕所有权的销售和登记的法律框架,才能真正让其发挥作用。ERC-994标准已经建立了一个系统,DNFT可以识别不同区域并委派其对房屋或土地进行标记,通过这种方式,财产的所有权将被合法通证化。

可拆解非同质化代币(Composable NFT,缩写为CNFT)。它的设计可以让任何一个NFT可以拥有其他NFT或FT。转移CNFT时,就是转移CNFT所拥有的整个层级结构和所属关系。简单来说就是一个ERC-998的物品可以包含多个ERC-721和ERC-20形式的物品。

譬如,在类似加密猫的区块链游戏KittyHats中,猫咪的属性是ERC-721,而猫咪的衣服同样也是ERC-721,而穿着衣服的猫咪,就意味着两个NFT的结合。ERC-998所做的事情就是建立一个相应的以ERC-721猫咪为父Token,ERC-721服装为子Token的新代币。如果我们现在要卖掉这只猫,先把它们整合成一个整体,这个整体依然是不可分割的,但包含了猫咪对衣服的所有权关系,然后对这个整体进行交易就可以。这会极大的简化物品转移的处理。

兼具了 NFT 和 FT 的特性,具有半同质化代币 (semi-fungible token)的特性。

可以用来把多个物品(Token)合并打包成一个物品(Token包)。举常见游戏插槽镶嵌的例子,一件有两个插槽的武器,和两个完美的符文,这是三个Token,当把这两个符文镶嵌进武器中,就变成一个新的武器,也就是Token包。ERC-1155融合了ERC-20和ERC-721的一些优点,开发者可以很方便的创建海量种类的物品,每个物品可以是ERC-721那样独立的,也可以像ERC-20一样同质化。

ERC-1155与传统的代币非常不同,不能直接销毁。相反,除非最初的开发人员定期买回代币,否则它们通常仍在流通。ERC-1155 的定位为更具体的代币标准,因为在此标准上任何资产都可以在任何给定时间创建和销毁。

最为典型的案例就是在ERC-1155协议中,最为典型的案例便是一款基于Web端口的区块链游戏War of Crypto(简称WOC)。

是ERC-809协议的升级版,相较于ERC-809协议,ERC-1201协议进一步扩展了NFT租赁的流动性。

如果说ERC-809是将NFT变得可以租赁,换句话说,就是加入rental前缀的ERC-721协议,那么ERC-1201协议则是将NFT的租赁权进行了通证化,类似于加入rental前缀的ERC-1155协议。

保险单是一类重要的金融资产,很自然地将这些资产表示为一类遵循既定的EIP-721标准的不可替代的代币。我们为唯一定义保险单所需的附带元数据结构提出了一个标准。

虽然保单可以具有多种可能的属性,但首先来说,通常由某个实体发布保单,该实体基本上是负责支付索赔的实体。其次,保险单通常与特定风险相关。某些风险是独一无二的,但在某些情况下,许多政策都具有相同的风险(例如,同一航班的所有航班延误政策)。

一般来说,政策与风险的关系是多对一的关系,特殊情况下是一对一的关系。

第三,大多数保单需要更多参数来表征风险和其他特征,如保费、期限等。

第四,保单具有不同状态的生命周期。我们认为这四个属性是描述策略所必需的。对于许多应用,这些特性甚至可能就足够了。但是,任何实现可以选择实现更多的属性。

在ERC-721的基础上,为NFT添加了一个32字节的数据字段,并且允许用户访问该NFT的读取功能。而该NFT的所有者还拥有更新数据的权限。通过这一设定,ERC-1948协议让NFT具有了存储动态数据的能力。

EIP-3664 由 DRepublic 团队在 2021 年 5 月份提出,他们使用了一种巧妙的方式,解决了现有 NFT 协议(如:ERC-721 或 ERC-1155)的属性表现力不足,NFT 之间无法融合,中心化存储等问题,实现了 NFT 属性动态扩展。

NFT 属性扩展协议(EIP-3664)无需修改现有的 ERC-721 协议和 ERC-1155 协议,支持通过在 NFT mint 方法的 IERC721Receiver 或 IERC1155Receiver 的回调函数中为 NFT attach attributes, 也可以通过 override mint 方法自定义实现为 NFT attach 属性的方式。一个 NFT 可以无限 attach 任意多个属性。

EIP-3664 中所有属性都实现了 IERC3664 接口,基础属性包含几个基本字段:ID, Name, Symbol, URI, Balance。从以上信息可以看出 ERC3664 把属性也 token 化了,甚至可以说每一个属性也是一种 NFT,这就衍生出了子 NFT 的概念,即 NFT 嵌套 NFT,这种特性看似简单,其实为 NFT 提供了无穷多的变化属性,并且让 NFT 的用途变得更为广泛。属性的更新,转移,进化各种变化都可以通过扩展基础的 ERC3664 协议来实现,目前 EIP-3664 已经实现了六种核心属性操作:可升级,可修改,可添加,可移除,可拆分,可组合。

以太坊虚拟机(EVM)是什么?

以太坊是一个可编程的区块链。与比特币不同,以太坊并没有给用户提供一组预定义的操作(比如比特币交易),而是允许用户创建他们自己的操作,这些操作可以任意复杂。这样,以太坊成为了多种不同类型去中心化区块链的平台,包括但是不限于密码学货币。

EVM为以太坊虚拟机。以太坊底层通过EVM模块支持智能合约的执行和调用,调用时根据合约的地址获取到代码,生成具体的执行环境,然后将代码载入到EVM虚拟机中运行。通常目前开发智能合约的高级语言为Solidity,在利用solidity实现智能合约逻辑后,通过编译器编译成元数据(字节码)最后发布到以坊上。

EVM架构概述

EVM本质上是一个堆栈机器,它最直接的的功能是执行智能合约,根据官方给出的设计原理,EVM的主要的设计目标为如下几点:

  简单性

  确定性

  空间节省

  为区块链服务

  安全性保证

  便于优化

针对以上几点通过对EVM源代码的阅读来了解其具体的设计思想和工程实用性。

EVM存储系统机器位宽

     EVM机器位宽为256位,即32个字节,256位机器字宽不同于我们经常见到主流的64位的机器字宽,这就标明EVM设计上将考虑一套自己的关于操作,数据,逻辑控制的指令编码。目前主流的处理器原生的支持的计算数据类型有:8bits整数,16bits整数,32bits整数,64bits整数。一般情况下宽字节的计算将更加的快一些,因为它可能包含更多的指令被一次性加载到pc寄存器中,同时伴有内存访问次数的减少。目前在X86的架构中8bits的计算并不是完全的支持(除法和乘法),但基本的数学运算大概在几个时钟周期内就能完成,也就是说主流的字节宽度基本上处理器能够原生的支持,那为什么EVM要采用256位的字宽。主要从以下两个方面考虑:

  时间,智能合约是否能执行得更快

  空间,这样是否整体字节码的大小会有所减少

  gas成本

时间上主要体现在执行的效率上,我们以两个整型数相加来对比具体的操作时间消耗。32bits相加的X86

的汇编代码

  mov eax, dword [9876ABCD] //将地址9876ABCD中的32位数据放入eax数据寄存器

    add eax, dword [1234DCBA] //将1234DCBA地址指向32位数和eax相加,结果保存在eax中

64bits相加的X86汇编代码

  mov rax, qword [123456789ABCDEF1] //将地址指向的64位数据放入64位寄存器

    add rax, qword [1020304050607080] //计算相加的结果并将结果放入到64位寄存器中

链乔教育在线旗下学硕创新区块链技术工作站是中国教育部学校规划建设发展中心开展的“智慧学习工场2020-学硕创新工作站 ”唯一获准的“区块链技术专业”试点工作站。专业站立足为学生提供多样化成长路径,推进专业学位研究生产学研结合培养模式改革,构建应用型、复合型人才培养体系。

用Go来做以太坊开发④智能合约

在这个章节中我们会介绍如何用Go来编译,部署,写入和读取智能合约。

与智能合约交互,我们要先生成相应智能合约的应用二进制接口ABI(application binary interface),并把ABI编译成我们可以在Go应用中调用的格式。

第一步是安装 Solidity编译器 ( solc ).

Solc 在Ubuntu上有snapcraft包。

Solc在macOS上有Homebrew的包。

其他的平台或者从源码编译的教程请查阅官方solidity文档 install guide .

我们还得安装一个叫 abigen 的工具,来从solidity智能合约生成ABI。

假设您已经在计算机上设置了Go,只需运行以下命令即可安装 abigen 工具。

我们将创建一个简单的智能合约来测试。 学习更复杂的智能合约,或者智能合约的开发的内容则超出了本书的范围。 我强烈建议您查看 truffle framework 来学习开发和测试智能合约。

这里只是一个简单的合约,就是一个键/值存储,只有一个外部方法来设置任何人的键/值对。 我们还在设置值后添加了要发出的事件。

虽然这个智能合约很简单,但它将适用于这个例子。

现在我们可以从一个solidity文件生成ABI。

它会将其写入名为“Store_sol_Store.abi”的文件中

现在让我们用 abigen 将ABI转换为我们可以导入的Go文件。 这个新文件将包含我们可以用来与Go应用程序中的智能合约进行交互的所有可用方法。

为了从Go部署智能合约,我们还需要将solidity智能合约编译为EVM字节码。 EVM字节码将在事务的数据字段中发送。 在Go文件上生成部署方法需要bin文件。

现在我们编译Go合约文件,其中包括deploy方法,因为我们包含了bin文件。

在接下来的课程中,我们将学习如何部署智能合约,然后与之交互。

Commands

Store.sol

solc version used for these examples

如果你还没看之前的章节,请先学习 编译智能合约的章节 因为这节内容,需要先了解如何将智能合约编译为Go文件。

假设你已经导入从 abigen 生成的新创建的Go包文件,并设置ethclient,加载您的私钥,下一步是创建一个有配置密匙的交易发送器(tansactor)。 首先从go-ethereum导入 accounts/abi/bind 包,然后调用传入私钥的 NewKeyedTransactor 。 然后设置通常的属性,如nonce,燃气价格,燃气上线限制和ETH值。

如果你还记得上个章节的内容, 我们创建了一个非常简单的“Store”合约,用于设置和存储键/值对。 生成的Go合约文件提供了部署方法。 部署方法名称始终以单词 Deploy 开头,后跟合约名称,在本例中为 Store 。

deploy函数接受有密匙的事务处理器,ethclient,以及智能合约构造函数可能接受的任何输入参数。我们测试的智能合约接受一个版本号的字符串参数。 此函数将返回新部署的合约地址,事务对象,我们可以交互的合约实例,还有错误(如果有)。

就这么简单:)你可以用事务哈希来在Etherscan上查询合约的部署状态:

Commands

Store.sol

contract_deploy.go

solc version used for these examples

这写章节需要了解如何将智能合约的ABI编译成Go的合约文件。如果你还没看, 前先读 上一个章节 。

一旦使用 abigen 工具将智能合约的ABI编译为Go包,下一步就是调用“New”方法,其格式为“Newcontractname style="box-sizing: border-box; font-size: 16px; -ms-text-size-adjust: auto; -webkit-tap-highlight-color: transparent;"”,所以在我们的例子中如果你 回想一下它将是 NewStore 。 此初始化方法接收智能合约的地址,并返回可以开始与之交互的合约实例。/contractname

Commands

Store.sol

contract_load.go

solc version used for these examples

这写章节需要了解如何将智能合约的ABI编译成Go的合约文件。如果你还没看, 前先读 上一个章节 。

在上个章节我们学习了如何在Go应用程序中初始化合约实例。 现在我们将使用新合约实例提供的方法来阅读智能合约。 如果你还记得我们在部署过程中设置的合约中有一个名为 version 的全局变量。 因为它是公开的,这意味着它们将成为我们自动创建的getter函数。 常量和view函数也接受 bind.CallOpts 作为第一个参数。了解可用的具体选项要看相应类的 文档 一般情况下我们可以用 nil 。

Commands

Store.sol

contract_read.go

solc version used for these examples

这写章节需要了解如何将智能合约的ABI编译成Go的合约文件。如果你还没看, 前先读 上一个章节 。

写入智能合约需要我们用私钥来对交易事务进行签名。

我们还需要先查到nonce和燃气价格。

接下来,我们创建一个新的keyed transactor,它接收私钥。

然后我们需要设置keyed transactor的标准交易选项。

现在我们加载一个智能合约的实例。如果你还记得 上个章节 我们创建一个名为 Store 的合约,并使用 abigen 工具生成一个Go文件。 要初始化它,我们只需调用合约包的 New 方法,并提供智能合约地址和ethclient,它返回我们可以使用的合约实例。

我们创建的智能合约有一个名为 SetItem 的外部方法,它接受solidity“bytes32”格式的两个参数(key,value)。 这意味着Go合约包要求我们传递一个长度为32个字节的字节数组。 调用 SetItem 方法需要我们传递我们之前创建的 auth 对象(keyed transactor)。 在幕后,此方法将使用它的参数对此函数调用进行编码,将其设置为事务的 data 属性,并使用私钥对其进行签名。 结果将是一个已签名的事务对象。

现在我就可以看到交易已经成功被发送到了以太坊网络了:

要验证键/值是否已设置,我们可以读取智能合约中的值。

搞定!

Commands

Store.sol

contract_write.go

solc version used for these examples

有时您需要读取已部署的智能合约的字节码。 由于所有智能合约字节码都存在于区块链中,因此我们可以轻松获取它。

首先设置客户端和要读取的字节码的智能合约地址。

现在你需要调用客户端的 codeAt 方法。 codeAt 方法接受智能合约地址和可选的块编号,并以字节格式返回字节码。

你也可以在etherscan上查询16进制格式的字节码

contract_bytecode.go

首先创建一个ERC20智能合约interface。 这只是与您可以调用的函数的函数定义的契约。

然后将interface智能合约编译为JSON ABI,并使用 abigen 从ABI创建Go包。

假设我们已经像往常一样设置了以太坊客户端,我们现在可以将新的 token 包导入我们的应用程序并实例化它。这个例子里我们用 Golem 代币的地址.

我们现在可以调用任何ERC20的方法。 例如,我们可以查询用户的代币余额。

我们还可以读ERC20智能合约的公共变量。

我们可以做一些简单的数学运算将余额转换为可读的十进制格式。

同样的信息也可以在etherscan上查询:

Commands

erc20.sol

contract_read_erc20.go

solc version used for these examples

有关智能合约多少字节,智能合约怎么写内容分享到这里,想要了解更多区块链内容请关注币杠财经网。

推荐阅读:

火网手机交易平台能充值吗 安卓手机交易平台怎么充值

中国比特币app安卓版下载(比特币手机交易软件)

怎么开户买比特币(什么网站可以注册比特币账户)