Skip to content

Instantly share code, notes, and snippets.

@juntao
Created September 13, 2018 06:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juntao/6ff0e639a6512cc1d8224a1cc27a623e to your computer and use it in GitHub Desktop.
Save juntao/6ff0e639a6512cc1d8224a1cc27a623e to your computer and use it in GitHub Desktop.
Scrypt on CyberMiles VM
# 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
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 = "0x608060405234801561001057600080fd5b506111d5806100206000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a83dc30614610046575b600080fd5b34801561005257600080fd5b5061015760048036038101908080359060200190929190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610171565b604051808215151515815260200191505060405180910390f35b600061017b611172565b606080600060c0604051908101604052808c81526020018b81526020018a81526020018981526020018881526020018781525093506101b98461030c565b92506102d360405160206040519081016040526001905260206040519081016040527f0400000000000000000000000000000000000000000000000000000000000000905260206040519081016040526001905260206040519081016040527f04000000000000000000000000000000000000000000000000000000000000009052602060405190810160405280600090528580516020019081604051908101604052905b602083101515610283578051825260208201915060208101905060208303925061025e565b6001836020036101000a0d8019825116818451168082178552505050505050806040518190039052907f7363727970740000000000000000000000000000000000000000000000000000f561082f565b91506102de876109ea565b9050806102ea83610a2e565b11156102f957600094506102fe565b600194505b505050509695505050505050565b60608060608060608060608060008060a06040519080825280601f01601f19166020018201604052801561034f5781602001602082028038833980820191505090505b5098506103696103648c600001516008610da2565b61082f565b97506103788b6020015161082f565b96506103878b6040015161082f565b95506103a061039b8c606001516008610da2565b61082f565b94506103af8b6080015161082f565b93506103c86103c38c60a001516008610da2565b61082f565b925060009050600091505b87518210156104865787828151811015156103ea57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561044957fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081806001019250506103d3565b600091505b865182101561053e5786828151811015156104a257fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561050157fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350818060010192505061048b565b600091505b85518210156105f657858281518110151561055a57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000289828060010193508151811015156105b957fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508180600101925050610543565b600091505b84518210156106ae57848281518110151561061257fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561067157fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081806001019250506105fb565b600091505b83518210156107665783828151811015156106ca57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002898280600101935081518110151561072957fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535081806001019250506106b3565b600091505b825182101561081e57828281518110151561078257fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000289828060010193508151811015156107e157fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350818060010192505061076b565b889950505050505050505050919050565b6060806060600084925060006002845181151561084857fe5b0614151561085257fe5b82516040519080825280601f01601f1916602001820160405280156108865781602001602082028038833980820191505090505b509150600090505b82518110156109df5782600282855103038151811015156108ab57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002828281518110151561090457fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350826001828551030381518110151561094857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f01000000000000000000000000000000000000000000000000000000000000000282600183018151811015156109a457fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060028101905061088e565b819350505050919050565b6000806000806109f985610a2e565b9250601863ff00000084169060020a900491506008600383030291508162ffffff84169060020a029050809350505050919050565b6000606060008084925060009050600091505b8251821015610d97576004819060020a0290507f30000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900460ff168383815181101515610aa957fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f0100000000000000000000000000000000000000000000000000000000000000900460ff1610158015610bec57507f39000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900460ff168383815181101515610b7857fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f0100000000000000000000000000000000000000000000000000000000000000900460ff1611155b15610cbe577f30000000000000000000000000000000000000000000000000000000000000007f010000000000000000000000000000000000000000000000000000000000000090048383815181101515610c4357fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f010000000000000000000000000000000000000000000000000000000000000090040360ff1681019050610d8a565b600a7f61000000000000000000000000000000000000000000000000000000000000007f010000000000000000000000000000000000000000000000000000000000000090048484815181101515610d1257fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027f01000000000000000000000000000000000000000000000000000000000000009004030160ff16810190505b8180600101925050610a41565b809350505050919050565b60606000606060006060604080519080825280601f01601f191660200182016040528015610ddf5781602001602082028038833980820191505090505b509250600093505b604084101561107057600f87167f010000000000000000000000000000000000000000000000000000000000000002915060007f010000000000000000000000000000000000000000000000000000000000000002827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191610158015610eb2575060097f010000000000000000000000000000000000000000000000000000000000000002827effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191611155b15610f8857817f010000000000000000000000000000000000000000000000000000000000000090047f30000000000000000000000000000000000000000000000000000000000000007f01000000000000000000000000000000000000000000000000000000000000009004017f0100000000000000000000000000000000000000000000000000000000000000028385603f03815181101515610f5357fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611058565b600a827f010000000000000000000000000000000000000000000000000000000000000090047f61000000000000000000000000000000000000000000000000000000000000007f0100000000000000000000000000000000000000000000000000000000000000900401037f0100000000000000000000000000000000000000000000000000000000000000028385603f0381518110151561102757fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b6004879060020a900496508380600101945050610de7565b8560ff166040519080825280601f01601f1916602001820160405280156110a65781602001602082028038833980820191505090505b509050600093505b8560ff168410156111655782848760400360ff16018151811015156110cf57fe5b9060200101517f010000000000000000000000000000000000000000000000000000000000000090047f010000000000000000000000000000000000000000000000000000000000000002818581518110151561112857fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535083806001019450506110ae565b8094505050505092915050565b60c06040519081016040528060008152602001606081526020016060815260200160008152602001606081526020016000815250905600a165627a7a7230582038802dc5aad6a913b855eb4cf2e625aea15168883684c587e2621db18efee4540029";
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);
}
);
pragma solidity ^0.4.23;
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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment