|
1 | 1 | ---
|
2 | 2 | sidebar_position: 5
|
3 | 3 | ---
|
| 4 | + |
4 | 5 | # 标准合约
|
| 6 | + |
| 7 | +本文档介绍了sCrypt语言的标准合约以及工具库。 |
| 8 | + |
| 9 | +合约之间可以互相调用,可以在一个合约中new出一个其他合约的对象,要求其他合约被解锁之后,当前合约才可以被解锁。 |
| 10 | + |
| 11 | +比如在P2PKH的合约中,可以要求P2PKH的解锁条件中同时满足HashPuzzle和P2PK两个合约。最终表现在链上的形态是一个大Utxo合约中封装了好几个小的合约代码,要求小合约代码全部被解锁才可以解锁大合约。 |
| 12 | + |
| 13 | +## Import |
| 14 | + |
| 15 | +可以将不同的合约或者library封装在不同的文件中,然后使用import语句来导入合约。 |
| 16 | + |
| 17 | +## Library |
| 18 | + |
| 19 | +library是一种特殊的合约,它只能被其他合约所调用,不能包含任何public方法。主要用来整理相关的参数和静态方法。 |
| 20 | + |
| 21 | +官方提供了一些标准合约,用来处理一些常见的场景,这些标准合约不需要被import就可以使用。 |
| 22 | + |
| 23 | +https://scryptdoc.readthedocs.io/en/latest/contracts.html#full-list |
| 24 | + |
| 25 | +| Contract | Constructor Parameters | Public Function | |
| 26 | +|------------------|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| 27 | +| Utils | None | `toLEUnsigned(int n, int l) : bytes`<br/>`fromLEUnsigned(bytes b) : int`<br/>`readVarint(bytes b) : bytes`<br/>`writeVarint(bytes b) : bytes`<br/>`buildOutput(bytes outputScript, int outputSatoshis) : bytes`<br/>`buildPublicKeyHashScript(PubKeyHash pubKeyHash) : bytes`<br/>`buildOpreturnScript(bytes data) : bytes`<br/>`isFirstCall(SigHashPreimage preimage) : bool` | |
| 28 | +| Tx | None | `checkPreimage(SigHashPreimage preimage) : bool`<br/>`checkPreimageOpt(SigHashPreimage rawTx) : bool`<br/>`checkPreimageOpt_(SigHashPreimage rawTx) : bool`<br/>`checkPreimageSigHashType(SigHashPreimage txPreimage, SigHashType sigHashType) : bool`<br/>`checkPreimageAdvanced(SigHashPreimage rawTx, PrivKey privKey, PubKey pubKey, int inverseK, int r, bytes rBigEndian, SigHashType sigHashType) : bool`<br/>`checkPreimageOCS(SigHashPreimage preimage) : bool`<br/>`checkPreimageOptOCS(SigHashPreimage rawTx) : bool`<br/>`checkPreimageOptOCS_(SigHashPreimage rawTx) : bool`<br/>`checkPreimageSigHashTypeOCS(SigHashPreimage txPreimage, SigHashType sigHashType) : bool`<br/>`checkPreimageAdvancedOCS(SigHashPreimage rawTx, PrivKey privKey, PubKey pubKey, int inverseK, int r, bytes rBigEndian, SigHashType sigHashType) : bool` | |
| 29 | +| SigHash | None | `nVersion(SigHashPreimage preimage) : bytes`<br/>`hashPrevouts(SigHashPreimage preimage) : bytes`<br/>`hashSequence(SigHashPreimage preimage) : bytes`<br/>`outpoint(SigHashPreimage preimage) : bytes`<br/>`scriptCode(SigHashPreimage preimage) : bytes`<br/>`valueRaw(SigHashPreimage preimage) : bytes`<br/>`value(SigHashPreimage preimage) : int`<br/>`nSequenceRaw(SigHashPreimage preimage) : bytes`<br/>`nSequence(SigHashPreimage preimage) : int`<br/>`hashOutputs(SigHashPreimage preimage) : bytes`<br/>`nLocktimeRaw(SigHashPreimage preimage) : bytes`<br/>`nLocktime(SigHashPreimage preimage) : int`<br/>`sigHashType(SigHashPreimage preimage) : SigHashType` | |
| 30 | +| HashedMap\<K, V> | bytes data | `set(SortedItem\<K> keyWithIdx, V val) : bool`<br/>`canGet(SortedItem\<K> keyWithIdx, V val) : bool`<br/>`delete(SortedItem\<K> keyWithIdx) : bool`<br/>`has(SortedItem\<K> keyWithIdx) : bool`<br/>`clear() : bool`<br/>`size() : int`<br/>`data() : bytes` | |
| 31 | +| HashedSet\<V> | bytes data | `add(SortedItem<\V> entryWithIdx) : bool`<br/>`delete(SortedItem<\V> entryWithIdx) : bool`<br/>`has(SortedItem<\V> entryWithIdx) : bool`<br/>`clear() : bool`<br/>`size() : int`<br/>`data() : bytes` | |
| 32 | + |
| 33 | +## Utils |
| 34 | + |
| 35 | +Util 是一些常用的工具类和方法,包含的方法列表如下: |
| 36 | + |
| 37 | + |
| 38 | + |
| 39 | +## Tx |
| 40 | + |
| 41 | +Tx library 包含读取当前交易信息的重要内容。这是实现有状态合约和约束后续合约的核心功能。 |
| 42 | + |
| 43 | +核心原理是使用一个伪操作吗OP_PUSH_TX,将当前交易的原像(preImage)推送到合约运行时中进行校验。preImage作为解锁参数的一部分,可以让合约感知到解锁自己的交易所具备的特点,针对这些特点来对交易能否解锁进行约束。(https://github.com/bitcoin-sv/bitcoin-sv/blob/master/doc/abc/replay-protected-sighash.md) |
| 44 | + |
| 45 | +注意,交易原像需要SIGHASH_FORKID的签名类型才可以生效,校验原像之前一定要校验签名类型SIG_HASH_ALL |
| 46 | + |
| 47 | +交易原像包括以下信息: |
| 48 | + |
| 49 | +1. nVersion of the transaction (4-byte little endian) |
| 50 | +2. hashPrevouts (32-byte hash) |
| 51 | +3. hashSequence (32-byte hash) |
| 52 | +4. outpoint (32-byte hash + 4-byte little endian) |
| 53 | +5. scriptCode of the input (serialized as scripts inside CTxOuts) |
| 54 | +6. value of the output spent by this input (8-byte little endian) |
| 55 | +7. nSequence of the input (4-byte little endian) |
| 56 | +8. hashOutputs (32-byte hash) |
| 57 | +9. nLocktime of the transaction (4-byte little endian) |
| 58 | +10. sighash type of the signature (4-byte little endian) |
| 59 | + |
| 60 | +校验原像主要包括 |
| 61 | + |
| 62 | +- checkPreimage() 原版pushTx |
| 63 | +- checkPreImageAdvanced() 高级版,增加更多可选参数 |
| 64 | +- checkPreImageOCS() 增加了OCS操作码的签名校验,不需要校验所有原像,只需要校验到checkPreimageOCS之前的一段即可,也就是签名使用部分原像的时候可以使用这个操作码,降低脚本体积。 |
| 65 | + |
| 66 | +## SigHash |
| 67 | + |
| 68 | +SigHash库主要用来访问原像中的数据,比如Sighash.scriptCode来获取scriptCode字段,使用SigHash.value 来获取value字段等。 |
| 69 | + |
| 70 | +交易原像包括以下信息(https://github.com/bitcoin-sv/bitcoin-sv/blob/master/doc/abc/replay-protected-sighash.md): |
| 71 | + |
| 72 | +1. nVersion of the transaction (4-byte little endian) (SPENDING TX的版本) |
| 73 | +2. hashPrevouts (32-byte hash) (SPENDING TX所有input outpoint的hash) |
| 74 | +3. hashSequence (32-byte hash) (SPENDING TX所有input的nSequence的hash) |
| 75 | +4. outpoint (32-byte hash + 4-byte little endian) (SPENDING TX当前input对应的outpoint) |
| 76 | +5. scriptCode of the input (serialized as scripts inside CTxOuts) (SPENT TX点位对应的UTXO脚本) |
| 77 | +6. value of the output spent by this input (8-byte little endian) (SPENT TX点位对应的金额) |
| 78 | +7. nSequence of the input (4-byte little endian) (SPENT TX点位对应的sequence) |
| 79 | +8. hashOutputs (32-byte hash) (SPENDING TX当前所有output脚本和金额的hash,这是限制后续交易格式的核心) |
| 80 | +9. nLocktime of the transaction (4-byte little endian) (SPENDING TX的nLockTime) |
| 81 | +10. sighash type of the signature (4-byte little endian) (SIGHASH类型) |
| 82 | + |
| 83 | +## HashedMap |
| 84 | + |
| 85 | +hashMap |
| 86 | +提供一种类似于map的功能,大部分的功能不仅需要key,也需要index。可以简单认为,这种map中的key是一个聚合类型,包含key本身和用来排序的index。称为SortedItem\<T> |
| 87 | + |
| 88 | +## HashedSet |
| 89 | + |
| 90 | +提供类似set的功能,和hashmap类似,也需要SortedItem整体作为key |
| 91 | + |
| 92 | +## Constants |
| 93 | + |
| 94 | +提供一些常用业务常量。 |
| 95 | + |
| 96 | +```cpp |
| 97 | +// number of bytes to denote input sequence |
| 98 | +static const int InputSeqLen = 4; |
| 99 | +// number of bytes to denote output value |
| 100 | +static const int OutputValueLen = 8; |
| 101 | +// number of bytes to denote a public key (compressed) |
| 102 | +static const int PubKeyLen = 33; |
| 103 | +// number of bytes to denote a public key hash |
| 104 | +static const int PubKeyHashLen = 20; |
| 105 | +// number of bytes to denote a tx id |
| 106 | +static const int TxIdLen = 32; |
| 107 | +// number of bytes to denote a outpoint |
| 108 | +static const int OutpointLen = 36; |
| 109 | +``` |
0 commit comments