连载:Qtum量子链设计文档(一)

量子链Qtum2018-06-03 16:34:29  阅读 -评论 0  阅读原文

连载:Qtum量子链设计文档(一)点击上方蓝字关注QTUM公众号,了解最新行业资讯

连载:Qtum量子链设计文档(一)

以下内容整理来自Qtum量子链吴明


前言


在本系列文章中,Qtum量子链基金会将首次公开其早期设计文档,希望帮助社区理解Qtum的设计初衷和各关键技术的实现细节。文章将会以原始的设计初稿为主,以便还原设计者最原始的想法。后续Qtum项目组会进行进一步整理和解读,帮助读者理解更多技术细节,敬请期待。

连载:Qtum量子链设计文档(一)

该系列文章中可能包含的主题包括

连载:Qtum量子链设计文档(一)

* Qtum账户抽象层AAL

* Qtum分布式自治协议DGP

* Qtum钱包(qt,移动端 钱包等)和 浏览器

* 新增RPC调用

* 互惠权益共识机制MPoS

* 新增opcode

* EVM与Qtum区块链的集成

* Qtum x86虚拟机

* 其他...

Qtum量子链公众号将会围绕上述主题进行不定期连载更新,还原Qtum项目和各关键技术从无到有,并不断发展完善的历史。

Qtum原始设计文档汇总(1)-- Qtum新增OPCODE

众所周知,Qtum底层采用与比特币一致的UTXO模型。原始的UTXO脚本无法兼容EVM的账户模型,因此Qtum 针对UTXO交易脚本新增了三个操作码OP_CREATE,OP_CALL和OP_SPEND,目的是用于为UTXO和EVM账户模型之间的转换提供操作支持。三个操作码的原始名称分别为OP_EXEC(OP_CREATE), OP_EXEC_ASSIGN(OP_CALL)和 OP_TXHASH(OP_SPEND)。

以下节选具有代表性的原始文档,供感兴趣的读者阅读。

OP_CREATE(或OP_EXEC)

OP_CREATE(或OP_EXEC)用于智能合约的创建,早期Qtum开发团队对此操作码的相关原始设计文档(附中文翻译)如下(ps:文档中QTUM或QTUMCORE为内部设计文档编号):

QTUMCORE-3:Add EVM and OP_CREATE for contract execution Description:After this story, the EVM should be integrated and a very basic contract should be capable of being executed. There will be a new opcode, OP_CREATE (formerly OP_EXEC), which takes 4 arguments, in push order: 1. VM version (currently 1 is EVM) 2. Gas price (not yet used, anything is valid) 3. Gas limit (not yet used, assume very high limit) 4. bytecodeFor now it is OK that this script format be forced and mandatory for OP_CREATE transactions on the blockchain. (ie, only "standard" allowed on the blockchain) When OP_CREATE is encountered, it should execute the EVM and persist the contract to a database (triedb) Note: Make sure to follow policy for external code (commit vanilla unmodified code first, and then change it as needed) Make the EVM test suite functional as well (someone else can setup continuous integration changes for it though)

Task:添加EVM和OP_CREATE操作码,使得可以运行合约
描述:该task完成后,EVM会被整合到代码中,并且能够运行非常基本的合约。增加一个新的操作码OP_CREATE(原来是OP_EXEC),该操作码有4个参数,下面4个参数按顺序压入栈中:

1 虚拟机版本号(目前EVM的版本号为1)
2 Gas price(暂时还没有使用,暂时可以是任何值)
3 Gas limit(暂时还没有使用,可以假设为一个很高的限定值)
4 字节码
目前为止,必须使用该脚本格式,并且对于区块链上的OP_CREATE格式也是强制使用该脚本格式。(即,区块链上只允许使用的“标准”)当遇到OP_CREATE时,应该执行EVM并将合约保存到数据库中(triedb)。
注意:
确保遵循外部代码的策略(首先提交vanilla未修改的代码,然后再根据需要修改)。保证EVM测试套件正常工作(其他人也能够进行后续integration改动)。

上述文档描述了OP_CREATE需要实现的功能及用到的参数。

OP_CALL(或OP_EXEC_ASSIGN)


OP_CALL用于合约的执行,是最常用的opcode之一,原始设计文档中对其有许多描述。

QTUM6: Implement calling environment info in EVM for OP_EXEC_ASSIGN
Description: Solidity expects certain information to be pushed onto the stack as part of it's ABI. So, when data is sent into the contract using OP_EXEC_ASSIGN we need to make sure to provide this data. This data includes the Solidity "function selector" as well as ensuring the opcodes CALLER and ORIGIN function properly. This looks to be fairly easy, it should just be transferring some data from the Bitcoin stack to the EVM stack, and setting some fields for the origin info. However, this story should be split into multiple tasks and re-evaluated if it isn't easy. See also: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI For populating the CALLER and ORIGIN value, the following should be done: OP_EXEC_ASSIGN should take 2 extra arguments, SENDER and SENDER_SIGNATURE. Sender should be a public key. Sender Signature is the signature of all the vins for the current transaction, signed of course using the SENDER value.On the EVM side, CALLER's value will be a public key hash, ie, a hash of the SENDER public key. This public key hash should be compatible with Bitcoin's public key hash for it's standard version 1 addresses. IF the given SENDER_SIGNATURE does not match successfully, then the transaction should be considered invalid. If the SENDER public key is 0, then SENDER_SIGNATURE must also be 0, and the given CALLER opcode etc should just return 0.

Task: 实现OP_EXEC_ASSIGN在EVM中的调用环境

描述:Solidity期望特定的信息可以压到栈内作为ABI的一部分。因此,当数据是通过OP_EXEC_ASSIGN被发送到合约时,我们必须确保能提供该数据。该数据包括Solidity“function selector”并且要确保opcode CALLER和ORIGIN正确运行。这看上去很简单,好像仅仅需要将一些数据从Bitcoin栈上转移到EVM栈上,并且为这些原始的信息设置一些字段就行。然而,这个任务需要分成多个任务实现,并且如果发现任务不简单的时需要重新进行评估。另请参阅:https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI为了获取CALLER和ORIGIN的值,需要做到以下几点:OP_EXEC_ASSIGN需要2个额外的参数,SENDER和SENDER_SIGNATURE。SENDER为一个公钥。SENDER_SIGNATURE为当前交易的所有输入(Vin)的签名,当然,都是使用SENDER值进行签名。EVM侧,CALLER的值是一个公钥哈希,例如一个SENDER公钥的哈希。该公钥哈希应该和Bitcoin的公钥哈希兼容,因为它是标准版本1的地址。如果给出的SENDER_SIGNATURE不能成功地匹配,那么这个交易会被认为是无效的。如果SENDER公钥为0,那么SENDER_SIGNATURE必须也为0,并且CALLER opcode等也应该返回0.

上述文档描述了OP_EXEC_ASSIGN在EVM中需要实现的调用环境信息。

QTUM8: Implement OP_EXEC_ASSIGN for sending money to contracts

Description: A new opcode should be added, OP_EXEC_ASSIGN. This opcode should take these arguments in push order: # version number (VM version to use, currently just 1)
# gas price (can be ignored for now)
# gas refund script (can be ignored for now)
# data (The data to hand to the smart contract. This will include things like the Solidity ABI Function Selector and other data that will later be available using the CALLERDATA EVM opcode) # smart contract address (txid + vout number)
It should return two values right now, 0 and 0. These are for spendable and out of gas, respectively. Making them spendable and dealing with out of gas will be in a future story For this story, the EVM contract does not actually need to be executed. This opcode should only be a placeholder so that the accounting system can determine how much money a contract has control of

Task:实现OP_EXEC_ASSIGN向合约发送QTUM功能

描述:增加一个新的opcode,OP_EXEC_ASSIGN。该opcode应该将以下参数按顺序压入栈中:
# 版本号(使用的虚拟机版本号,目前只有版本1)
# gas price(目前可以忽略)
# gas返还脚本 (目前可以忽略)
# 数据(传给智能合约的数据。包括Solidity ABI Function Selector和其他由CALLEDDATA EVM Opcode提供的数据等)
# 智能合约地址(txid + vout number)
OP_EXEC_ASSIGN应该立刻返回两个值,0和0。它们分别代表可花费的和缺少gas。使它们变成可花费的以及如何处理缺少gas这两个问题将会是后面需要处理的task。在该任务中,EVM合约实际上不需要被运行。该opcode仅仅是一个占位符(placeholder)以便于让记账系统可以确定一个合约能控制多少钱。

上述文档描述了OP_EXEC_ASSIGN的实现细节。

QTUM15: Execute the relevant contract during OP_EXEC_ASSIGN

Description: After this story is complete, when OP_EXEC_ASSIGN is reached, it should actually execute the contract whose address was given to it, passing the relevant data from the bitcoin script stack with it. Other data such as the caller and sender can be left for a later story. Making the CALLER, ORIGIN etc opcodes work properly will be fixed with a later story

Task:在OP_EXEC_ASSIGN期间运行相关的合约

描述:当OP_EXEC_ASSIGN到达时,实际上应该运行传入OP_EXEC_ASSIGN中的地址对应的合约,并将相关数据从脚本堆栈中传递出来。其他数据例如调用方和发送方可以作为下一个task。后面的task中也会进行一些修订,使CALLER和ORIGIN等opcode能够正常工作。

上述文档描述OP_EXEC_ASSIGN脚本如何运行相关合约代码。

QTUM40: Allow contracts to send money to pubkeyhash addresses Description: We need to allow contracts to send money back to pubkeyhash addresses, so that people can withdraw their coins from contracts when allowed, etc. This should work similar to how version 0 contract sends work. Instead of using an OP_EXEC_ASSIGN vout though, we need to instead use a standard pubkeyhash script. So, upon spending to a pubkeyhash, the following transaction should be placed on the blockchain: vin: [standard contract OP_EXEC_ASSIGN inputs] ... vout: OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG change output - version 0 OP_EXEC_ASSIGN back to spending contract These outputs should be directly spendable in the wallet with no changes to the wallet code itself Task:允许合约将钱发送给pubkeyhash地址
描述:允许合约将钱发送给pubkeyhash地址,以便在允许的情况下人们可以从合约中撤回自己的币等等。这和版本0合约发送的方法类似。但是,我们需要使用一个标准的公钥哈希脚本,而不是使用一个OP_EXEC_ASSIGN输出。因此,一旦给一个pubkeyhash地址发送钱后,下面的交易就应该放置在区块链上:
vin: [standard contract OP_EXEC_ASSIGN inputs] ... vout: OP_DUP OP_HASH160 [pubKeyHash] OP_EQUALVERIFY OP_CHECKSIG change output(找回的零钱 output) - version 0 OP_EXEC_ASSIGN back to spending contract

这些output在钱包中是可直接花费的,并且不会对钱包代码本身产生什么改变。

上述文档描述如何允许合约发送QTUM到pubkeyhash地址。

QTUMCORE-10:Add ability for contracts to call other deployed contracts Description:Contracts should be capable of calling other contracts using a new opcode, OP_CALL. Arguments in push order:version (32 bit integer) gas price (64 bit integer) gas limit (64 bit integer) contract address (160 bits) data (any length) OP_CALL should ways return false for now. OP_CALL only results in contract execution when used in a vout; Similar to OP_CREATE, it uses the special rule to process the script during vout processing (rather than when spent as is normal in Bitcoin). Contract execution should only be triggered when the transaction script is in this standard format and has no extra opcodes. If OP_CALL is created that uses an invalid contract address, then no contract execution should take place. The transaction should still be valid in the blockchain however. If money was sent with OP_CALL, then that money (minus the gas fees) should result in a refund transaction to send the funds back to vin[0]'s vout script. The "sender" exposed to EVM should be the pubkeyhash spent by vin[0]. If the vout spent by vin[0] is not a pubkeyhash, then the sender should be 0.Funds can be sent to the contract using an OP_CALL vout. These funds will be handled by the account abstraciton layer in a different story, to expose this to the EVM. Multiple OP_CALLS can be used in a single transaction. However, before contract execution, the gas price and gas limit of each OP_CALL vout should be checked to ensure that the transaction provides enough transaction fees to cover the gas. Additionally, this should be verified even when the contract is not executed, such as when it is accepted in the mempool.

Task:增加合约可调用其他已部署合约的功能
描述:合约可以使用一个新的操作码OP_CALL调用其他合约。下面的参数按照顺序压入栈中:
• 版本号(32bit整形)
• gas price(64bit整形)
• gas limit(64bit整形)
• 合约地址(160bits)
• 数据(任意长度)OP_CALL目前应该返回false。
OP_CALL仅在vout中使用时才导致合约执行;与OP_CREATE类似,在vout处理过程中,OP_CALL使用特殊的规则处理脚本(而不是像在比特币中那样正常使用)。只有当交易脚本是标准格式并且没有额外的操作码时,才会触发合约执行。如果使用无效的合约地址创建OP_CALL,则不应该执行合约。但是在区块链中交易仍然是有效的。如果使用OP_CALL发送资金,那么这笔资金(减去gas费用)会导致一个退款交易,该交易会将找零返回给vin[0]的vout脚本。向EVM公开的“发送方”应该为vin[0]所花费的公钥哈希。如果vin[0]所花费的vout不是公钥哈希,那么发送方应该为0。应该使用OP_CALL vout将资金发送给合约。这些资金将会被另一个story中的账户抽象层处理,然后将其发送给EVM。在单个交易中可以使用多个OP_CALLS。然而,在合约执行前,每个OP_CALL 输出的gas price和gas limit都应该检查,以确保该交易能提供足够的交易费用来覆盖gas费用。此外,即使合约不执行,这点也需要进行验证,例如当它在内存池中被接受时(就需要检查)。

上述文档描述了合约如何通过OP_CALL调用其他合约。

OP_SPEND(或OP_TXHASH,OP_EXEC_SPEND)

OP_SPEND用于合约余额的花费,由于合约地址是特殊的地址,为保证共识,需要对其UTXO进行特殊处理,因此原始设计文档中也有较多针对OP_SPEND操作码的描述。

QTUM20: Create OP_EXEC_SPEND transaction when a contract spends money

Description: When a CALL opcode or similar to used from an EVM contract to send another contract money, this should be shown on the blockchain as a new transaction. When a money transfer is done in the contract, the miner should add a new transaction exactly after the currently processing transaction in the block. This transaction should spend an input owned by the contract by using EXEC_SPEND in it's redeemScript. For the purposes of this story, assume change is not something to be worried about and consume as many inputs are needed. Properly picking effecient coins and sending back money to the originating contract will come in a later story. Edge cases to watch for: The transaction for sending money to the contract must come directly after the executing transaction. The outputs should use a version-0 OP_EXEC_ASSIGN vout, so that if the transaction were received out of context, it would still mean to not execute the contract.

Task:当合约花费资金的时候创建OP_EXEC_SPEND交易

描述:当一个CALL操作码或者其他类似的操作将资金从一个EVM合约发送给另一个合约时,这在区块链上也是作为一个新的交易显示。当资金的转移是通过合约来进行时,矿工应该在区块中当前正在处理的交易后添加一个新的交易。该交易通过在合约的redeem脚本中使用EXEC_SPEND来花费该合约的一个输入(input)。对于这个任务的目标,假设不考虑找零,且花费尽量多的输入。正确的选择有效的币以及将资金发送回原始的合约将会是后面的task需要解决的事情。
需要注意的边界情况:
用于给合约发送资金的交易必须直接跟在正在运行的交易的后面。输出应该使用版本0的OP_EXEC_ASSIGN vout,这样的话,即使接收到的交易语意不明,它仍然意味着不执行该合约。

上述文档描述创建OP_SPEND交易的时机。

QTUM21: Create consensus-critical change and coin-picking algorithm for OP_EXEC_SPEND transactions Description: Building on #20, now a consensus-critical algorithm must be made that picks the most optimal outputs belonging to the contract, and spends them, and also makes a change output that returns the "change" from the transaction back to the contract. All outputs in this case should be using a version-0 OP_EXEC_ASSIGN, to avoid running into the limitation that prevents more than one (version 1) OP_EXEC_ASSIGN transaction from being in a single transaction. The transaction should have as many vins as needed, and exactly 2 vouts. The first vout to go to the target contract, and the second vout to send change back to the source contract. Task:为OP_EXEC_SPEND交易进行共识层相关的修改以及coin-picking算法描述:在#20的基础上,我们需要一个涉及到共识层的算法用于选择属于合约的最优输出(outputs),并且花费这些output,同时也要做一些改变使得从交易中的找回的零钱可以返回给合约。这种场景下,所有的输出应该使用版本0的OP_EXEC_ASSIGN,避免出现多于1(version 1)个OP_EXEC_ASSIGN交易不能出现在单个交易中的情况。该交易应该有所需数量一样多的vin,并且只有2个vout。第一个vout用于目标合约,第二个vout用于将零钱发回给原合约。

QTUM22: Disallow more than one EVM execution per transaction

Description: In order to avoid significant edge cases, for now, disallow more than one EVM execution to take place in a single transaction. This includes both deployment and fund assignment vouts. Instead, such things should be split into multiple transactions If two EVM executions are encountered, the transaction should be treated as completely invalid and not suitable for broadcast nor putting into a block

Task:每个交易中只允许一次EVM运行
描述:为了避免一些重要的边界情况,目前不允许在一个单个的交易中有超过1个的EVM运行。这也包括部署和资金分配vout的情况。这些情况应该被分成多个交易。如果出现了两个EVM运行相遇的情况,那么该交易应该被视为完全无效并且不适合广播也不能放入区块中。

QTUM23: Add "version 0" OP_EXEC_ASSIGN, which does not execute EVM Description: To counteract problems from #22, we should allow OP_EXEC_ASSIGN to be used to fund a contract without the contract actually being executed. This will be used later for "change" outputs to (multiple) contracts. If the version number passed in for OP_EXEC_ASSIGN is 0, then the contract is not executed. Also, this is only valid if the data provided to OP_EXEC_ASSIGN is just a single byte "0". Multiple version-0 OP_EXEC_ASSIGN vouts should be valid in a transaction, or 1 non-version-0 OP_EXEC_ASSIGN (or an OP_EXEC deployment) and multiple version-0 OP_EXEC_ASSIGN vouts. This will be used for all money spending that is sent from a contract to another contract

Task:添加版本0的OP_EXEC_ASSIGN,该OP_EXEC_ASSIGN不运行EVM
描述:为了避免#22产生的问题,我们应该允许在合约实际上没有运行的情况下OP_EXEC_ASSIGN可以用于给合约分配资金。这将会用来解决合约找零output的问题。假如传入OP_EXEC_ASSIGN的版本号是0,那么合约就不运行。同样,这也只有在提供给OP_EXEC_ASSIGN的数据为单个字节0的时候才是有效的。在一个交易中具有多个版本0 的OP_EXEC_ASSIGN vout是有效的,或者具有1个非版本0的OP_EXEC_ASSIGN(或一个OP_EXEC部署)和多个版本0的OP_EXEC_ASSIGN vout也是有效的。这将用于从一个合约发送到另一个合约的所有资金花费。

上述三个文档描述了如果通过共识相关的coin-picking算法保证OP_SPEND操作码不会引起共识错误,保证找零正确。同时描述了合约无需运行的情况和处理方式。

QTUM34: Disallow OP_EXEC and OP_EXEC_ASSIGN from coinbase transactions Description: Because of problems with coinbase maturity and potential side effects from ordering of gas-refund scripts, it should not be legal for coinbase outputs to be anything which results in EVM execution or directly changing EVM account balances. This includes version 0 OP_EXEC_ASSIGN outputs.

Task:不允许在coinbase脚本中包含OP_EXEC和OP_EXEC_ASSIGN脚本
描述:由于coinbase需要一段成熟期以及gas返还脚本的顺序带来的潜在副作用,coinbase的任何会导致EVM运行或者直接改变EVM账户余额的输出都是不合法的。也包括版本0的OP_EXEC_ASSIGN输出。

上述文档规定coinbase交易中不应包含合约相关脚本。

其他相关文档

除此之外,还有部分文档描述新的操作码需要用到的基础设施。

QTUMCORE-51:Formalize the version field for OP_CREATE and OP_CALL Description:In order to sustain future extensions to the protocol, we need to set some rules for how we will later upgrade and add new VMs by changing the "version" argument to OP_CREATE and OP_CALL. We need a definitive VM version format beyond our current "just increment when doing upgrades". This would allow us to more easily plan upgrades and soft-forks. Proposed fields:
1. VM Format (can be increased from 0 to extend this format in the future):
2 bits2. Root VM - The actual VM to use, such as EVM, Lua, JVM, etc: 6 bits
3. VM Version - The version of the Root VM to use (for upgrading the root VM with backwards compatibility) - 8 bits
4. Flag options - For flags to the VM execution and AAL: 16 bits Total: 32 bits (4 bytes). Size is important since it will be in every EXEC transaction
Flag option bits that control contract creation: (only apply to OP_CREATE)
• 0 (reserve) Fixed gas schedule - if true, then this contract chooses to opt-out of allowing different gas schedules. Using OP_CALL with a gas schedule other than the one specified in it's creation will result in an immediate exception and result in an out of gas refund condition
• 1 (reserve) Enable contract admin interface (reserve only, this will be implemented later. Will allow contracts to control for themselves what VM versions and such they allow, and allows the values to be changed over the lifecycle of the contract)
• 2 (reserve) Disallow version 0 funding - If true, this contract is not capable of receiving money through version 0 OP_CALL, other than as required for the account abstraction layer.
• bits 3-15 available for future extensions Flag options that control contract calls: (only apply to OP_CALL)
• (none yet) Flag options that control both contract calls and creation:
• (none yet) These flags will be implemented in a later story Note that the version field now MUST be a 4 byte push. A standard EVM contract would now use the version number (in hex) "01 00 00 00" Consensus behavior: VM Format must be 0 to be valid in a block Root VM can be any value. 1 is EVM, 0 is no-exec. All other values result in no-exec (allowed, but the no execution, for easier soft-forks later)   VM Version can be any value (soft-fork compatibility). If a new version is used than 0 (0 is initial release version), then it will execute using version 0 and ignore the value Flag options can be any value (soft-fork compatibility). (inactive flag fields are ignored) Standard mempool behavior: VM Format must be 0Root VM must be 0 or 1VM Version must be 0Flag options - all valid fields can be set. All fields that are not assigned must be set to 0Defaults for EVM:VM Format: 0Root VM: 1VM Version: 0Flags: 0

Task:正式确定OP_CREATE 和OP_CALL的version字段

描述:为了支持未来对协议的扩展,我们需要为以后如何升级设置一些规则,并且通过改变“版本”参数为OP_CREATE 和OP_CALL添加新的虚拟机。我们需要一个确定的虚拟机版本格式,超出我们当前的“仅仅在升级的时候增加版本号”的方法。这将使我们更容易地计划升级和软分叉。建议的字段:

1. 虚拟机格式(可以从0增加到未来扩展这种格式):2bits
2. Root(根)VM -- 实际使用的虚拟机,例如EVM,Lua,JVM等等:6bits
3. 虚拟机版本 -- 使用的Root VM的版本(用于升级具有向后兼容性的root VM):8bits
4. Flag选项 -- 虚拟机运行和账户抽象层的flags:16bits

总共:32bits(4字节)。大小是很重要的,因为它会出现在每个EXEC交易中。控制合约创建的Flag选项bits(仅应用于OP_CREATE):
• 0(预留)固定的gas计划 -- 如果为true,那么合约选择不允许不同的gas安排。使用具有一个gas安排的OP_CALL,该gas计划不包括创建时指定的gas计划,将导致立即的异常,并导致out of gas退款情况。
• 1(预留)启动合约管理接口(保留,后面将会实现。将允许合约自行控制虚拟机版本和允许的内容,并且允许在合约的生命周期中值可以更改)。
• 2(预留)不允许版本0提供资金 -- 如果为true,合约不能通过版本0的OP_CALL接收资金,除非账户抽象层需要资金
• bits3-15用于未来的扩展控制合约调用的flag选项(仅应用于OP_CALL):
• 暂无
控制合约调用和创建的flag选项:
• 暂无
这些flag将会在后面的task中实现。
注意,现在的版本字段必须为4字节。
标准的EVM合约现在使用版本号“01 00 00 00”(十六进制形式)共识行为:
在区块中,虚拟机格式必须为0才是有效的。
Root VM可以为任何值。1代表EVM,0是no-exec。所有其他的值导致no-exec(允许,但是不运行,为了后面可以更容易进行软分叉)。VM版本可以是任何值(软分叉兼容)。如果使用了一个新的版本,这个版本不是0(0是初始发布的版本),那么它将使用版本0运行并且忽略该值。Flag选项可以使任何值(软分叉兼容)
(忽略不活跃的flag字段)
标准的内存池行为:
VM格式必须为0Root VM必须为0或1
VM版本必须为0
Flag选项 -- 所有有效字段都可以设置。所有没有分配的字段必须设置为0.
EVM的默认值:
VM格式:0Root
VM:1
VM版本:
0Flags:0

上述文档正式确定了OP_CREATE和OP_CALL需要用到的版本信息,为后续Qtum的多虚拟机支持铺平了道路。

QTUMCORE-52:Contract Admin Interface Description:(note, this isn't a goal for mainnet, though it would be a nice feature to include) It should be possible to manage the lifecycle of a contract internally within the contract itself. Such variables and configuration values that might need to be changed over the course of a contract's lifecycle: • Allowable gas schedules
• Allowable VM versions (ie, if a future VM version breaks this contract, don't allow it to be used, as well as deprecating past VM versions from being used to interact with this contract)
Creation flags (the version flags in OP_CREATE) All of these variables must be able to be controlled within the contract itself, using decentralized code. For instance, in a DAO scenario, it might be something that participants can vote on within the contract, and then the contract triggers the code that changes these parameters. In addition, a contract should be capable of detecting it's own settings throughout it's execution as well as when it is initially created. I propose implementing this interface as a special pre-compiled contract. For a contract ot interact with it, it would call it using the Solidity ABI like any other contract. Proposed ABI for the contract:
• `bytes[2048] GasSchedule(int n)`
• `int GasScheduleCount()`
• `int AddGasSchedule(bytes[2048]`
• `bytes[32] AllowedVMVersions()`
• `void SetAllowedVMVersions(bytes[32])` Alternative implementations: There could be a specific Solidity function which is called in order to validate that the contract should allow itself to be called in a particular manner: pragma solidity ^0.4.0; contract BlockHashTest {function BlockHashTest() { }function ValidateGasSchedule(bytes32 addr) public returns (bool) {if(addr=="123454") { return true; //allow contract to run }return false; //do not allow contract to run}function ValidateVMVersion(byte version) public returns (bool){if(version >= 2 && version < 10) { return true; //allow to run on versions 2-9. Say for example 1 had a vulnerability in it, and 10 broke the contract }return false; } } In this way a contract is responsible for managing it's own state. The basic way it would work is that when a you use OP_CALL to call a contract, it would first execute these two functions (and their execution would be included in gas costs). If either function returns false, then it immediately triggers an out of gas condition and cancels execution. It's slightly complicated to manage the "ValidateVMVersion" callback however, because we must decide which VM version to use. A bad one could cause this function itself to misbehave. Task:合约管理接口(Contract Admin Interface)
描述:(注意这不是主网的目标,尽管包含它是一个很好的特性)在合约本身内部可以管理合约的生命周期。在合约的生命周期中可能需要更改这类变量和配置值:
• 允许的gas schedule
• 允许的VM版本(即,如果将来的VM版本破坏了这个合约,那么不允许使用它,也不允许使用过去的VM版本和此合约交互)
• 创建flags(在OP_CREATE中的版本flags)
所有这些变量必须能够有合约本身控制,使用去中心化的代码。例如,在DAO场景中,参与者可以在合约中进行投票,然后合约触发修改这些参数的代码。此外,合约应该能够在整个运行过程中以在它最初被创建时检测到自己的设置。我建议将该接口实现为一种特殊的预编译合约。对于与它交互的合约,可以像任何其他合约一样使用Solidity ABI调用。建议的合约ABI:
• `bytes[2048] GasSchedule(int n)`
• `int GasScheduleCount()`
• `int AddGasSchedule(bytes[2048]`
• `bytes[32] AllowedVMVersions()`
• `void SetAllowedVMVersions(bytes[32])`
替代的实现:
可以有一个特殊的Solidity函数,调用该函数可以验证合约是否允许其本身以特定的方式被调用:

pragma solidity ^0.4.0; contract BlockHashTest {function BlockHashTest() { }function ValidateGasSchedule(bytes32 addr) public returns (bool) {if(addr=="123454") { return true; //allow contract to run }return false; //do not allow contract to run}function ValidateVMVersion(byte version) public returns (bool){if(version >= 2 && version < 10) { return true; //allow to run on versions 2-9. Say for example 1 had a vulnerability in it, and 10 broke the contract }return false; }
}

这样,合约就负责管理自己的状态。其工作的基本方法是,当你使用OP_CALL调用合约时,它将首先运行这两个函数(并且它们的运行将包含在gas成本中)。如果两个中的任何一个函数返回false,那么它将立刻触发一个out of gas错误并取消执行。然而,管理“ValidateVMVersion”回调函数有点复杂,因为我们必须决定使用哪个VM版本。一个不好的VM版本可能导致这个函数本身的错误行为。

上述文档描述了合约的管理接口,是的合约能够管理自己的状态。

QTUMCORE-53:Add opt-out flags to contracts for version 0 sends Description:Some contracts may wish to opt-out of certain features in Qtum that are not present in Ethereum. This way more Ethereum contracts can be ported to Qtum without worrying about new features in the Qtum blockchain Two flag options should be added to the Version field, which only have an effect in OP_CREATE for creating the contract: 2. (1st bit) Disallow "version 0" OP_CALLs to this contract outside of the AAL. (DisallowVersion0)  If this is enabled, then an OP_CALL using "root VM 0" (which causes no execution) is not allowed to be sent to this contract. If money is attempted to be sent to this contract using "version 0" OP_CALL, then it will result in an out of gas exception and the funds should be refunded. Version 0 payments made internally within the Account Abstraction Layer should not be affected by this flag. Along with these new consensus rules, there should also be some standard mempool checks:
1. If an OP_CALL tx uses a different gas schedule than the contract creation, and the disallow dynamic gas flag is set, then the transaction should be rejected from the mempool as a non-standard transaction (version 0 payments should not be allowed as standard transactions in the mempool anyway)

task:为version 0合约添加opt-out标志

描述:一些合约可能希望opt-out某些以太坊中不存在但Qtum中存在的特性。这样,更多的以太坊合约可以移植到Qtum,而不需要担心Qtum区块链的新特性。版本字段中应该添加两个flag选项,这只有在创建合约的时候才会对OP_CREATE有影响:
1. (第一个bit)不允许在账户抽象层之外的合约中使用“版本0”OP_CALLs。(DisallowVersion0)
• 如果启用了这个功能,那么使用“root VM 0”的OP_CALL(会导致不运行)不允许发送给该合约。如果是使用“版本0”OP_CALL将资金发送给该合约,那么它将导致一个out of gas异常,并且资金会被退回。账户抽象层内部生成的版本0支付不应受该flag的影响。除了这些新的共识规则,还应该有一些标准的内存池检查:
2. 如果一个OP_CALL交易使用与合约创建时不同的gas schedule,并且设置了不允许动态gas的flag,那么交易应该被内存池拒绝,因为它是一个非标准的交易。(无论如何,在内存池中不允许使用版本0支付作为标准的交易。)

上述文档描述了如何通过忽略某些Qtum特有的特性,从而获得更好的EVM兼容性,以便移植以太坊合约代码。这使得以太坊生态中的智能合约能够更容易的被Qtum兼容。

小结

以上展示的Qtum原始设计文档描述了Qtum增加的与合约运行相关的opcode,为后续Qtum在UTXO模型之上兼容账户模型的EVM虚拟机打下了基础,也使得账户抽象层AAL成为可能。后续Qtum项目组会对关键文档作进一步解读。读者如果有任何疑问,可以在评论区中发表见解,或与Qtum项目组联系。

Qtum量子链公众号将会围绕上述主题进行不定期连载更新,还原Qtum项目和各关键技术从无到有,并不断发展完善的历史。

连载:Qtum量子链设计文档(一)

关注Qtum量子链(qtumchain)公众号,回复关键字查阅Qtum量子链相关资料,以下是部分文档关键字

回复:‘白皮书’,查看《Qtum量子链白皮书,设计原理,实现方案,及应用》

回复:‘未来’,查看《Qtum量子链未来2年技术路线规划-简略版》

回复:‘指南’,查看《首篇Qtum量子链区块链开发指南系列面世》

回复:‘专访’,查看《Nasdaq专访Qtum:区块链会成为世界最大的信任服务商》

回复:‘文档’,查看英文版本《Qtum量子链实现文档》

回复:‘中文文档’,查看中文版本《Qtum量子链实现文档》

连载:Qtum量子链设计文档(一)

连载:Qtum量子链设计文档(一)

声明:链世界登载此文仅出于分享区块链知识,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不构成投资建议。投资者据此操作,风险自担。此文如侵犯到您的合法权益,请联系我们kefu@lianshijie.com

参与讨论 (0 人参与讨论)

相关推荐

Bebt交易所:深入分析自动化做市商发展掣肘与设计改进

Bebt交易所:深入分析自动化做市商发展掣肘与设计改进

在基于区块链的分布式系统 (如 Ethereum) 上重构一个新的金融世界时,必须认识到区块链世界与链下世界相比,有着完全不同的动态属性。最值得注意的是,链上并非连续计时,而是通过区块来量化时间的流逝。但因为它受到区块大小的限制,这又导致了延迟问题和计算能力的限制。由于这些结构上的差异,分布式金融的设计者应该具有与中心化世界的设计者完全不同的思路。例如,由于区块链的成本和技术基础设施,做市商在基于

谁是更好的去中心化云存储?Filecoin vs Storj设计要点和实测PK

而真正能算得上在去中心化云存储赛道主战场上正面PK的重量级选手,其实只有Filecoin和Storj。

解构灰度比特币信托产品的设计原理

原文标题:解构灰度比特币信托原文作者:Ann Hsu | Chain Hill Capital首席指数分析师本文系Chain Hill Capital首席指数分析师Ann Hsu 撰写,未经授权严禁转

西班牙央行将评估数字货币设计提案,计划持续到2021年底

西班牙央行将评估数字货币设计提案,计划持续到2021年底

作为欧元区成员国之一,西班牙央行并不能单方面发行本国的主权CBDC。这项工作的预期结果将在2021年中期确定。

Qtum 量子链提速计划:区块时间从2分钟提速至16秒

从上线开始,Qtum 量子链的目标区块间隔一直为128秒。对于Qtum主网,孤立区块出现的概率目前为2%至3%。致谢作者感谢Qtum 量子链基金会的领导层和核心开发团队为减少区块间距而进行的架构设计。

红枣科技何亦凡“BSN设计本源:对区块链未来的理解”

红枣科技何亦凡“BSN设计本源:对区块链未来的理解”

2020年9月16日,第三届中国国际区块链+商业未来发展峰会在鹭岛厦门国际会展中心圆满举行。本次峰会由厦门市人民政府、中国商业联合会、福建省数字福建建设领导小组办公室指导,厦门市工业和信息化局、福建省区块链协会、BSN发展联盟支持,熵链学派、思尔福智慧零售主办,链闻、Winkrypto联合主办。会议以"应用无界 创新价值"为主题,汇聚福建省各地级市政府有关部门负责人、行业权威专家、领军企业代表、创

比特币即将接入波卡,一文了解PolkaBTC的设计和路线图

2021 年初,Interlay 将推出 Polkadot 的首个无信任包装的比特币 PolkaBTC,这是波卡迈向真正互操作生态系统的关键一步。保险库是无需信任和担保的中介机构,确保在PolkaBTC存在的情况下,比特币仍被锁定在比特币网络上。

比特币有什么缺点?

1.交易平台的脆弱性。比特币网络很健壮,但比特币交易平台很脆弱。交易平台通常是一个网站,而网站会遭到黑客攻击,或者遭到主管部门的关闭。2.交易确认时间长。比特币钱包初次安装时,会消耗大量时间下载历史交易数据块。而比特币交易时,为了确认数据准确性,会消耗一些时间,与p2p网络进行交互,得到全网确认后,交易才算完成。3.价格波动极大。由于大量炒家介入,导致比特币兑换现金的价格如过山车一般起伏。使得比

麦妖榜
更新日期 2019-09-03
排名用户贡献值
1牛市来了30910
2BitettFan24187
3等待的宿命23810
4区块大康20369
5六叶树20310
6linjm122719429
7天下无双16192
8lizhen00215280
9让时间淡忘14586
10yelanyi050511349
返回顶部 ↑