/
verify-dogecoin-block-on-travis.rst
234 lines (193 loc) · 28.7 KB
/
verify-dogecoin-block-on-travis.rst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
Verify Dogecoin Block on Travis
===============================
.. _verify-dogecoin-block-on-travis:
Dogecoin verifier is a smart contract on Travis to verify correctness of Dogecoin block header and its pow hash. There is a step by step tutorial for running Dogecoin verifier on Travis locally.
Scrypt ENI Library
------------------
Dogecoin uses scrypt as its PoW hash algorithm. Our scrypt ENI library provides a simple interface for using scrypt:
- Input: :code:`[0-9a-fA-F]{0,160}`, hex format of 0 to 80 bytes data
- Output: :code:`[0-9a-f]{64}` hex format of 32 bytes data
Compile DogecoinVerifier Contract
---------------------------------
There is a simple contract that leverage ENI to do heavy scrypt hash algorithm.
.. code::
pragma lity ^1.2.4;
contract DogecoinVerifier {
struct DogecoinBlockHeader {
uint version;
string prev_block;
string merkle_root;
uint timestamp;
string bits;
uint nonce;
}
function verifyBlock(uint version, string prev_block, string merkle_root, uint timestamp, string bits, uint nonce) pure public returns (bool) {
DogecoinBlockHeader memory block_header = DogecoinBlockHeader(version, prev_block, merkle_root, timestamp, bits, nonce);
string memory block_header_hex = generateBlockHeader(block_header);
string memory pow_hash = reverseHex(eni("scrypt", block_header_hex));
uint256 target = bitsToTarget(bits);
if (hexToUint(pow_hash) > target) {
return false;
}
return true;
}
function generateBlockHeader(DogecoinBlockHeader header) pure internal returns (string) {
bytes memory block_header = new bytes(160);
bytes memory version_hex = bytes(reverseHex(uintToHex(header.version, 8)));
bytes memory prev_block_hex = bytes(reverseHex(header.prev_block));
bytes memory merkle_root_hex = bytes(reverseHex(header.merkle_root));
bytes memory timestamp_hex = bytes(reverseHex(uintToHex(header.timestamp, 8)));
bytes memory bits_hex = bytes(reverseHex(header.bits));
bytes memory nonce_hex = bytes(reverseHex(uintToHex(header.nonce, 8)));
uint i;
uint index = 0;
for (i = 0; i < version_hex.length; i++) { block_header[index++] = version_hex[i]; }
for (i = 0; i < prev_block_hex.length; i++) { block_header[index++] = prev_block_hex[i]; }
for (i = 0; i < merkle_root_hex.length; i++) { block_header[index++] = merkle_root_hex[i]; }
for (i = 0; i < timestamp_hex.length; i++) { block_header[index++] = timestamp_hex[i]; }
for (i = 0; i < bits_hex.length; i++) { block_header[index++] = bits_hex[i]; }
for (i = 0; i < nonce_hex.length; i++) { block_header[index++] = nonce_hex[i]; }
return string(block_header);
}
function bitsToTarget(string bits) pure internal returns (uint) {
uint bits_uint32 = hexToUint(bits);
uint p = (bits_uint32 & 0xff000000) >> 24;
p = (p - 3) * 8;
uint result = (bits_uint32 & 0xffffff) << p;
return result;
}
function reverseHex(string hex_string) pure internal returns (string) {
bytes memory hex_bytes = bytes(hex_string);
assert(hex_bytes.length % 2 == 0);
bytes memory outpute_bytes = new bytes(hex_bytes.length);
for (uint i = 0; i < hex_bytes.length; i += 2) {
outpute_bytes[i] = hex_bytes[hex_bytes.length - i - 2];
outpute_bytes[i + 1] = hex_bytes[hex_bytes.length - i - 1];
}
return string(outpute_bytes);
}
function hexToUint(string hex_string) pure internal returns (uint256) {
bytes memory hex_bytes = bytes(hex_string);
uint i;
uint256 result = 0;
for (i = 0; i < hex_bytes.length; i++) {
result <<= 4;
if (uint8(hex_bytes[i]) >= uint8(byte('0')) && uint8(hex_bytes[i]) <= uint8(byte('9'))) {
result += uint8(hex_bytes[i]) - uint8(byte('0'));
} else {
result += uint8(hex_bytes[i]) - uint8(byte('a')) + 10;
}
}
return result;
}
function uintToHex(uint256 a, uint8 length) pure internal returns (string) {
uint i;
bytes memory hex_bytes = new bytes(64);
for (i = 0; i < 64; i++) {
byte last_half_byte = byte(a & 0xf);
if (last_half_byte >= 0 && last_half_byte <= 9) {
hex_bytes[63 - i] = byte(uint8(byte('0')) + uint8(last_half_byte));
} else {
hex_bytes[63 - i] = byte(uint8(byte('a')) + uint8(last_half_byte) - 10);
}
a >>= 4;
}
bytes memory output_bytes = new bytes(length);
for (i = 0; i < length; i++) {
output_bytes[i] = hex_bytes[64 - length + i];
}
return string(output_bytes);
}
}
and we could compile it using :code:`lityc`:
.. code:: bash
$ mkdir output
$ lityc --abi --bin -o output DogecoinVerifier.sol
$ cat output/DogecoinVerifier.abi
[{"constant":true,"inputs":[{"name":"version","type":"uint256"},{"name":"prev_block","type":"string"},{"name":"merkle_root","type":"string"},{"name":"timestamp","type":"uint256"},{"name":"bits","type":"string"},{"name":"nonce","type":"uint256"}],"name":"verifyBlock","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"}]
$ cat output/DogecoinVerifier.bin
608060405234801561001057600080fd5b506111e3806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a83dc30614610046575b600080fd5b34801561005257600080fd5b5061015760048036038101908080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610171565b604051808215151515815260200191505060405180910390f35b600061017b611180565b606080600060c0604051908101604052808c81526020018b81526020018a81526020018981526020018881526020018781525093506101b98461031a565b92506102e160405160206040519081016040526001905260206040519081016040527f0400000000000000000000000000000000000000000000000000000000000000905260206040519081016040526001905260206040519081016040527f04000000000000000000000000000000000000000000000000000000000000009052602060405190810160405280600090528580516020019081601f0160209004602002604051908101604052905b60208310151561028d5780518252602082019150602081019050602083039250610268565b6001836020036101000a0d801982511681845116808217855250505050505080604051819003602090039052907f7363727970740000000000000000000000000000000000000000000000000000f561083d565b91506102ec876109f8565b9050806102f883610a3c565b1115610307576000945061030c565b600194505b505050509695505050505050565b60608060608060608060608060008060a06040519080825280601f01601f19166020018201604052801561035d5781602001602082028038833980820191505090505b5098506103776103728c600001516008610db0565b61083d565b97506103868b6020015161083d565b96506103958b6040015161083d565b95506103ae6103a98c606001516008610db0565b61083d565b94506103bd8b6080015161083d565b93506103d66103d18c60a001516008610db0565b61083d565b925060009050600091505b87518210156104945787828151811015156103f857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561045757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081806001019250506103e1565b600091505b865182101561054c5786828151811015156104b057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561050f57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610499565b600091505b855182101561060457858281518110151561056857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000289828060010193508151811015156105c757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610551565b600091505b84518210156106bc57848281518110151561062057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561067f57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610609565b600091505b83518210156107745783828151811015156106d857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561073757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081806001019250506106c1565b600091505b825182101561082c57828281518110151561079057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000289828060010193508151811015156107ef57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610779565b889950505050505050505050919050565b6060806060600084925060006002845181151561085657fe5b0614151561086057fe5b82516040519080825280601f01601f1916602001820160405280156108945781602001602082028038833980820191505090505b509150600090505b82518110156109ed5782600282855103038151811015156108b957fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002828281518110151561091257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350826001828551030381518110151561095657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000282600183018151811015156109b257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060028101905061089c565b819350505050919050565b600080600080610a0785610a3c565b9250601863ff00000084169060020a900491506008600383030291508162ffffff84169060020a029050809350505050919050565b6000606060008084925060009050600091505b8251821015610da5576004819060020a0290507f30000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900460ff168383815181101515610ab757fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f0100000000000000000000000000000000000000000000000000000000000000900460ff1610158015610bfa57507f39000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900460ff168383815181101515610b8657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f0100000000000000000000000000000000000000000000000000000000000000900460ff1611155b15610ccc577f30000000000000000000000000000000000000000000000000000000000000007f010000000000000000000000000000000000000000000000000000000000000090048383815181101515610c5157fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090040360ff1681019050610d98565b600a7f61000000000000000000000000000000000000000000000000000000000000007f010000000000000000000000000000000000000000000000000000000000000090048484815181101515610d2057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004030160ff16810190505b8180600101925050610a4f565b809350505050919050565b60606000606060006060604080519080825280601f01601f191660200182016040528015610ded5781602001602082028038833980820191505090505b509250600093505b604084101561107e57600f87167f010000000000000000000000000000000000000000000000000000000000000002915060007f010000000000000000000000000000000000000000000000000000000000000002827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610158015610ec0575060097f010000000000000000000000000000000000000000000000000000000000000002827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b15610f9657817f010000000000000000000000000000000000000000000000000000000000000090047f30000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000009004017f0100000000000000000000000000000000000000000000000000000000000000028385603f03815181101515610f6157fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611066565b600a827f010000000000000000000000000000000000000000000000000000000000000090047f61000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900401037f0100000000000000000000000000000000000000000000000000000000000000028385603f0381518110151561103557fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b6004879060020a900496508380600101945050610df5565b8560ff166040519080825280601f01601f1916602001820160405280156110b45781602001602082028038833980820191505090505b509050600093505b8560ff168410156111735782848760400360ff16018151811015156110dd57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002818581518110151561113657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535083806001019450506110bc565b8094505050505092915050565b60c06040519081016040528060008152602001606081526020016060815260200160008152602001606081526020016000815250905600a165627a7a7230582055b141ab4ed35af0047852953c43a6e4a9f9b782f0b81af72497b3238c5971640029
Deploy contract to Travis locally
---------------------------------
After we get contract ABI and bytecode, we could deploy it to Travis chain.
.. code:: bash
# Get Travis console
travis attach http://127.0.0.1:8545
# Deploy contract (in Travis console)
personal.unlockAccount(cmt.accounts[0], '1234');
abi = [{"constant":true,"inputs":[{"name":"version","type":"uint256"},{"name":"prev_block","type":"string"},{"name":"merkle_root","type":"string"},{"name":"timestamp","type":"uint256"},{"name":"bits","type":"string"},{"name":"nonce","type":"uint256"}],"name":"verifyBlock","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"}];
bytecode = "0x608060405234801561001057600080fd5b506111e3806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a83dc30614610046575b600080fd5b34801561005257600080fd5b5061015760048036038101908080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610171565b604051808215151515815260200191505060405180910390f35b600061017b611180565b606080600060c0604051908101604052808c81526020018b81526020018a81526020018981526020018881526020018781525093506101b98461031a565b92506102e160405160206040519081016040526001905260206040519081016040527f0400000000000000000000000000000000000000000000000000000000000000905260206040519081016040526001905260206040519081016040527f04000000000000000000000000000000000000000000000000000000000000009052602060405190810160405280600090528580516020019081601f0160209004602002604051908101604052905b60208310151561028d5780518252602082019150602081019050602083039250610268565b6001836020036101000a0d801982511681845116808217855250505050505080604051819003602090039052907f7363727970740000000000000000000000000000000000000000000000000000f561083d565b91506102ec876109f8565b9050806102f883610a3c565b1115610307576000945061030c565b600194505b505050509695505050505050565b60608060608060608060608060008060a06040519080825280601f01601f19166020018201604052801561035d5781602001602082028038833980820191505090505b5098506103776103728c600001516008610db0565b61083d565b97506103868b6020015161083d565b96506103958b6040015161083d565b95506103ae6103a98c606001516008610db0565b61083d565b94506103bd8b6080015161083d565b93506103d66103d18c60a001516008610db0565b61083d565b925060009050600091505b87518210156104945787828151811015156103f857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561045757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081806001019250506103e1565b600091505b865182101561054c5786828151811015156104b057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561050f57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610499565b600091505b855182101561060457858281518110151561056857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000289828060010193508151811015156105c757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610551565b600091505b84518210156106bc57848281518110151561062057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561067f57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610609565b600091505b83518210156107745783828151811015156106d857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561073757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081806001019250506106c1565b600091505b825182101561082c57828281518110151561079057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000289828060010193508151811015156107ef57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610779565b889950505050505050505050919050565b6060806060600084925060006002845181151561085657fe5b0614151561086057fe5b82516040519080825280601f01601f1916602001820160405280156108945781602001602082028038833980820191505090505b509150600090505b82518110156109ed5782600282855103038151811015156108b957fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002828281518110151561091257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350826001828551030381518110151561095657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000282600183018151811015156109b257fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060028101905061089c565b819350505050919050565b600080600080610a0785610a3c565b9250601863ff00000084169060020a900491506008600383030291508162ffffff84169060020a029050809350505050919050565b6000606060008084925060009050600091505b8251821015610da5576004819060020a0290507f30000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900460ff168383815181101515610ab757fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f0100000000000000000000000000000000000000000000000000000000000000900460ff1610158015610bfa57507f39000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900460ff168383815181101515610b8657fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f0100000000000000000000000000000000000000000000000000000000000000900460ff1611155b15610ccc577f30000000000000000000000000000000000000000000000000000000000000007f010000000000000000000000000000000000000000000000000000000000000090048383815181101515610c5157fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090040360ff1681019050610d98565b600a7f61000000000000000000000000000000000000000000000000000000000000007f010000000000000000000000000000000000000000000000000000000000000090048484815181101515610d2057fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004030160ff16810190505b8180600101925050610a4f565b809350505050919050565b60606000606060006060604080519080825280601f01601f191660200182016040528015610ded5781602001602082028038833980820191505090505b509250600093505b604084101561107e57600f87167f010000000000000000000000000000000000000000000000000000000000000002915060007f010000000000000000000000000000000000000000000000000000000000000002827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610158015610ec0575060097f010000000000000000000000000000000000000000000000000000000000000002827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b15610f9657817f010000000000000000000000000000000000000000000000000000000000000090047f30000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000009004017f0100000000000000000000000000000000000000000000000000000000000000028385603f03815181101515610f6157fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611066565b600a827f010000000000000000000000000000000000000000000000000000000000000090047f61000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900401037f0100000000000000000000000000000000000000000000000000000000000000028385603f0381518110151561103557fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b6004879060020a900496508380600101945050610df5565b8560ff166040519080825280601f01601f1916602001820160405280156110b45781602001602082028038833980820191505090505b509050600093505b8560ff168410156111735782848760400360ff16018151811015156110dd57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002818581518110151561113657fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535083806001019450506110bc565b8094505050505092915050565b60c06040519081016040528060008152602001606081526020016060815260200160008152602001606081526020016000815250905600a165627a7a7230582055b141ab4ed35af0047852953c43a6e4a9f9b782f0b81af72497b3238c5971640029";
contract = web3.cmt.contract(abi);
c = contract.new(
{
from: web3.cmt.accounts[0],
data: bytecode,
gas: "4700000"
},
function(e, contract) {
console.log("contract address: " + contract.address);
console.log("transactionHash: " + contract.transactionHash);
}
);
Use contract to verify pow hash
-------------------------------
It's time to verify block header using deployed contract.
Here we use `block #2 of dogecoin <https://dogechain.info/block/ea5380659e02a68c073369e502125c634b2fb0aaf351b9360c673368c4f20c96>`_ as an example.
To verify a block, we need the following block header information:
- version
- previous block hash
- transaction merkle root hash
- timestamp
- difficulty (bits)
- nonce
In block 2, these values in block header are:
- version: :code:`1`
- previous block hash: :code:`82bc68038f6034c0596b6e313729793a887fded6e92a31fbdf70863f89d9bea2`
- transaction merkle root hash: :code:`3b14b76d22a3f2859d73316002bc1b9bfc7f37e2c3393be9b722b62bbd786983`
- timestamp: :code:`1386474933` (convert from :code:`2013-12-07 19:55:33 -0800`)
- difficulty (bits): :code:`1e0ffff0`
- nonce: :code:`3404207872`
Back to our DogecoinVerifier contract. The :code:`verifyBlock` function use ENI library to compute scrypt hash of block header,
and check the correctness of PoW result. The funcntion will return :code:`true` if this block header is valid.
.. code:: bash
# Block #2 of dogecoin
> c.verifyBlock.call(1, "82bc68038f6034c0596b6e313729793a887fded6e92a31fbdf70863f89d9bea2", "3b14b76d22a3f2859d73316002bc1b9bfc7f37e2c3393be9b722b62bbd786983", 1386474933, "1e0ffff0", 3404207872)
true
# Even 1-bit of nonce changed, this block header will become invalid
> c.verifyBlock.call(1, "82bc68038f6034c0596b6e313729793a887fded6e92a31fbdf70863f89d9bea2", "3b14b76d22a3f2859d73316002bc1b9bfc7f37e2c3393be9b722b62bbd786983", 1386474933, "1e0ffff0", 3404207871)
false
# You could also use sendTransaction to verifyBlock function
> t = c.verifyBlock.sendTransaction(2, "12aca0938fe1fb786c9e0e4375900e8333123de75e240abd3337d1b411d14ebe", "31757c266102d1bee62ef2ff8438663107d64bdd5d9d9173421ec25fb2a814de", 1392346781, "1b267eeb", 2216773632, {from:web3.cmt.accounts[0], gas: 1000000});
# We set the gas limit to 1000000 and verifyBlock function only costs 243583 gas
> cmt.getTransaction(t)
{
blockHash: "0x46fc1763dd3c761e84c6f0a6eb430333c0eb8b3b33d8d2d6098d48b3b7662459",
blockNumber: 39,
from: "0x7eff122b94897ea5b0e2a9abf47b86337fafebdc",
gas: 1000000,
gasPrice: 2000000000,
hash: "0xa401b964930848e44af24a31338a58ca1f75e32a0abbb0f978ad3c519595e04a",
input: "0xa83dc306000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000052fd869d0000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000008421480000000000000000000000000000000000000000000000000000000000000000403132616361303933386665316662373836633965306534333735393030653833333331323364653735653234306162643333333764316234313164313465626500000000000000000000000000000000000000000000000000000000000000403331373537633236363130326431626565363265663266663834333836363331303764363462646435643964393137333432316563323566623261383134646500000000000000000000000000000000000000000000000000000000000000083162323637656562000000000000000000000000000000000000000000000000",
nonce: 1,
r: "0x62d1d11973bfd94f05daa86708806d23cadbb1f33b6d7b5cc1e2bec90d50907",
s: "0x26df72607d09561de0d2507a8d5789676ddc4ce93ee3ac67f976ee64a61911c5",
to: "0xb6b29ef90120bec597939e0eda6b8a9164f75deb",
transactionIndex: 0,
v: "0x4a",
value: 0
}
> cmt.getTransactionReceipt(t)
{
blockHash: "0x46fc1763dd3c761e84c6f0a6eb430333c0eb8b3b33d8d2d6098d48b3b7662459",
blockNumber: 39,
contractAddress: null,
cumulativeGasUsed: 243583,
from: "0x7eff122b94897ea5b0e2a9abf47b86337fafebdc",
gasUsed: 243583,
logs: [],
logsBloom: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
root: "0xaa9759a788044dbad69ae99e521c1c5969e0b4e52e17284313ce367f3df48f9e",
to: "0xb6b29ef90120bec597939e0eda6b8a9164f75deb",
transactionHash: "0xa401b964930848e44af24a31338a58ca1f75e32a0abbb0f978ad3c519595e04a",
transactionIndex: 0
}