diff --git a/.travis.yml b/.travis.yml index 79b4cc2..a67bd0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,6 +38,7 @@ install: - pip install git+https://github.com/goacoincore/neoscrypt - pip install git+https://github.com/motioncrypto/x16r_hash - pip install pycryptodomex + - pip install git+https://github.com/Electra-project/nist5_hash # command to run tests script: - pytest --cov=electrumx diff --git a/electrumx/lib/coins.py b/electrumx/lib/coins.py index 61b2732..df602c8 100644 --- a/electrumx/lib/coins.py +++ b/electrumx/lib/coins.py @@ -2877,3 +2877,33 @@ class Onixcoin(Coin): '''Given a header return the hash.''' import x11_hash return x11_hash.getPoWHash(header) + + +class Electra(Coin): + NAME = "Electra" + SHORTNAME = "ECA" + NET = "mainnet" + XPUB_VERBYTES = bytes.fromhex("0488b21e") + XPRV_VERBYTES = bytes.fromhex("0488ade4") + P2PKH_VERBYTE = bytes.fromhex("21") + P2SH_VERBYTES = [bytes.fromhex("28")] + WIF_BYTE = bytes.fromhex("A1") + GENESIS_HASH = ('00000f98da995de0ef1665c7d3338687' + '923c1199230a44ecbdb5cec9306e4f4e') + RPC_PORT = 5788 + TX_COUNT = 615729 + TX_COUNT_HEIGHT = 205243 + TX_PER_BLOCK = 3 + REORG_LIMIT = 100 + DESERIALIZER = lib_tx.DeserializerElectra + + @classmethod + def header_hash(cls, header): + '''Given a header return the hash.''' + version, = util.unpack_le_uint32_from(header) + import nist5_hash + + if version != 8: + return nist5_hash.getPoWHash(header) + else: + return double_sha256(header) diff --git a/electrumx/lib/tx.py b/electrumx/lib/tx.py index 12af880..a58a7ef 100644 --- a/electrumx/lib/tx.py +++ b/electrumx/lib/tx.py @@ -797,3 +797,29 @@ class DeserializerBitcoinDiamondSegWit(DeserializerBitcoinDiamond, we process it in the natural serialized order. ''' return self._read_tx_parts()[0] + + +class DeserializerElectra(Deserializer): + ELECTRA_TX_VERSION = 7 + + def _get_version(self): + result, = unpack_le_int32_from(self.binary, self.cursor) + return result + + def read_tx(self): + version = self._get_version() + if version != self.ELECTRA_TX_VERSION: + return TxTime( + self._read_le_int32(), # version + self._read_le_uint32(), # time + self._read_inputs(), # inputs + self._read_outputs(), # outputs + self._read_le_uint32(), # locktime + ) + else: + return Tx( + self._read_le_int32(), # version + self._read_inputs(), # inputs + self._read_outputs(), # outputs + self._read_le_uint32() # locktime + ) diff --git a/tests/blocks/electra_mainnet_120000.json b/tests/blocks/electra_mainnet_120000.json new file mode 100644 index 0000000..f2ca182 --- /dev/null +++ b/tests/blocks/electra_mainnet_120000.json @@ -0,0 +1,20 @@ +{ + "hash": "ed87415eec682bd45915cf9b58c3240937373b5904e2e781504960930400228d", + "size": 821, + "height": 120000, + "version": 6, + "merkleroot": "9ff8c579c4929aa1aa1e6a9a704e36afa7e075f6f555dfa915af27f5c6fcb9c0", + "tx": [ + "7e95106d7f2f9ce046c97e991aedb13ca631633b5d93aea216dc24ab05303a11", + "3f4cfbc123c934ab983c989e3ed81cc8a3296a696474a589e7fae45cc22a14fa", + "793b99eb068bd837743e5730b75739254095efc0ea70a1480e8488c73050e6de" + ], + "time": 1539998087, + "nonce": 0, + "bits": "1b094a51", + "difficulty": 7054.132896662391, + "chainwork": "0000000000000000000000000000000000000000000000005e21e43dfb3d33a6", + "previousblockhash": "3471e0e3d5bda84109f9e9a0676d36d4e2448c4ae22283af8b117300380c95c8", + "nextblockhash": "5488c63f091160dd27a070fdc6a4a261d838dbdd84570f6170f6b9fa34ba8a90", + "block": "06000000c8950c380073118baf8322e24a8c44e2d4366d67a0e9f90941a8bdd5e3e07134c0b9fcc6f527af15a9df55f5f675e0a7af364e709a6a1eaaa19a92c479c5f89f8781ca5b514a091b0000000003010000008781ca5b010000000000000000000000000000000000000000000000000000000000000000ffffffff0403c0d401ffffffff0100000000000000000000000000010000008781ca5b01a943749d1b322c6cc73d09aed39ac5f98b7d949663a65e11b450d73854023cc1010000004847304402205b7c7fb4ef30a134e803521ee883e1439f6425f5850a0758382a04ba3bd133900220289f23f63ada2785d22b150f88afe8ab037766e37e76b00a726558151dea0e2101ffffffff03000000000000000000c0ce822556db0000232102755f8f296fc1e5e643b9f90415144f9311e029d8e284bdaac838b45c3d32cd55ac88e0832556db0000232102755f8f296fc1e5e643b9f90415144f9311e029d8e284bdaac838b45c3d32cd55ac0000000001000000fc80ca5b029ec3ff99757227d7aafb90829b56307716b250ac0967e8574661a99e036db165000000006a473044022051edc0e5ab66205d6e28d7c02f41458059d109823a7a2d2007bdb274c48dd68a02200654c59f234fa370a602dd45ed6039c09057d70ed337d1d03215bd8e082bd5f80121022adbff4e8ad66004fe7ab9a72cac0f53b64cad3ecba683c923a22a16f23a4683ffffffffcb3100ffd79b9a3ff3da51d68a6768473f57f6e4b9909e818c76f6041e7a2a7c000000006b483045022100bace32c50fa6ba9840d7685ac2a85afaf0214b6239082b023f53a411f45ca4b702205f0d12ec1ec101df8e3a37f5288daaa9d312f72d2b822d4dd551b331e5ac4e6001210206970eaf01f12e516da6ced85bf623c59450676a42c2ea3b40f7179974975252ffffffff021cd46e0f000000001976a91492dd2d2a436680ff82c814da03477a3d1be295e188ac7aa91989020000001976a9140a237dd29cc896e96ad996aa689056575c48bb0388ac00000000463044022026caa49a29231a9490215d13843dbe5c8067f4a92f9487cff3d6f77341896c0302206ce90a5724d699d29a5e32a12c85d0d7ea49a7279f14a1c9611850866b8ad904" +} \ No newline at end of file diff --git a/tests/blocks/electra_mainnet_200000.json b/tests/blocks/electra_mainnet_200000.json new file mode 100644 index 0000000..36331d2 --- /dev/null +++ b/tests/blocks/electra_mainnet_200000.json @@ -0,0 +1,19 @@ +{ + "hash": "eb35558f177a902e165a54474bfd465c6fab11c4131fa9963cc224267bde1cb7", + "size": 438, + "height": 200000, + "version": 8, + "merkleroot": "3fe27f540667f559da14159ed95f51a990a80bc08a266a89338b02c211b8fe78", + "tx": [ + "7e5a915352a2941063a3cdb9319c2384857f7c3f97be68a0835a5fe8b2adc4e0", + "3672944d4e16e8c76a09c8bb2cfbe5c8fdfdef3416b28e87359b6aa660059aca" + ], + "time": 1551967523, + "nonce": 0, + "bits": "1949405a", + "difficulty": 58632371.88655923, + "chainwork": "000000000000000000000000000000000000000000000184aa9c6381e7103e02", + "previousblockhash": "b0d74219e3802621250af7ea50b858321fa360762bbaddf3968c1c044ba483e7", + "nextblockhash": "4c1e839bcad65f4e7ea257db6169b5f025c13ac8f07825f70c93aa56d8cd0cb3", + "block": "08000000e783a44b041c8c96f3ddba2b7660a31f3258b850eaf70a25212680e31942d7b078feb811c2028b33896a268ac00ba890a9515fd99e1514da59f56706547fe23f2325815c5a404919000000000207000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0603400d030101ffffffff01000000000000000000000000000700000001e01bde66c2b1fbf602c78ce2f43cbc53517d86b1caef3396962a881872c84bc4020000004847304402203bf1a143b384d257cf0f25803307c688fb09b1fdf57d310eea45beee8b6c85e002200dfef2703b80ccd6d7f30b32e702af7654d51f026dd1cd39f1cb8b25ce1b49ed01ffffffff03000000000000000000c02d08cdaa19000023210242a06ef798e2c434aba6fcdf5c30c80ce4382d722e19a4e85f91db67d6698b39acbf4c0dcdaa19000023210242a06ef798e2c434aba6fcdf5c30c80ce4382d722e19a4e85f91db67d6698b39ac00000000463044022055c7116568454603aa4529b399f2bcb50cb6e6ec9d64e1c8c95444fe1d38dca902202452c53ee34befaf525c5c91be465488c14a447838976a8f16255fc9bff6090e" +} \ No newline at end of file