def SearchAssetState(self, query): res = [] snapshot = self._db.createSnapshot() keys = [] with self._db.openIter( DBProperties(DBPrefix.ST_Asset, include_value=False)) as it: for key in it: keys.append(key[1:]) # remove prefix byte if query.lower() == "neo": query = "AntShare" if query.lower() in {"gas", "neogas"}: query = "AntCoin" for item in keys: asset = snapshot.Assets.TryGet(item) if query in asset.Name.decode('utf-8'): res.append(asset) elif query in Crypto.ToAddress(asset.Issuer): res.append(asset) elif query in Crypto.ToAddress(asset.Admin): res.append(asset) return res
def test_invocation_assetcreate_block(self): hexdata = binascii.unhexlify(self.asset_create_block) block = Helper.AsSerializableWithType(hexdata, 'neo.Core.Block.Block') self.assertEqual(block.Index, self.asset_create_index) result = Blockchain.Default().Persist(block) self.assertTrue(result) # now the asset that was created should be there assets = DBCollection(Blockchain.Default()._db, DBPrefix.ST_Asset, AssetState) newasset = assets.TryGet(self.asset_create_id) self.assertIsNotNone(newasset) self.assertEqual(newasset.AssetType, 1) self.assertEqual(newasset.Precision, 8) self.assertEqual(Crypto.ToAddress(newasset.Admin), self.asset_admin) self.assertEqual(Crypto.ToAddress(newasset.Issuer), self.asset_admin) self.assertIsInstance(newasset.AssetId, UInt256) self.assertEqual(newasset.AssetId.ToBytes(), self.asset_create_id)
async def verify_signature(message): """ Verifies a signature of a message, return True if verified, false if not """ Crypto.SetupSignatureCurve() try: signature = json.loads(message['signature']) except Exception: LOGGER.exception("NEO Signature deserialization error") return False try: script_hash = Crypto.ToScriptHash("21" + signature['publicKey'] + "ac") address = Crypto.ToAddress(script_hash) except Exception: LOGGER.exception("NEO Signature Key error") return False if address != message['sender']: LOGGER.warning('Received bad signature from %s for %s' % (address, message['sender'])) return False try: verification = await buildNEOVerification(message, signature['salt']) result = Crypto.VerifySignature(verification, bytes.fromhex(signature['data']), bytes.fromhex(signature['publicKey']), unhex=True) except Exception: LOGGER.exception("NULS Signature verification error") result = False return result
def test_invocation_assetcreate_block(self): hexdata = binascii.unhexlify(self.asset_create_block) block = Helper.AsSerializableWithType(hexdata, 'neo.Core.Block.Block') self.assertEqual(block.Index, self.asset_create_index) snapshot = Blockchain.Default()._db.createSnapshot() snapshot.PersistingBlock = block snapshot.UnspentCoins.Add(b'aa2051096e7be45ed991279a1a4c2678eb886690829a2729f4caa82192ff7f34', UnspentCoinState.FromTXOutputsConfirmed([0])) result = False with BlockchainFixtureTestCase.MPPersist(): result = Blockchain.Default().Persist(block, snapshot) self.assertTrue(result) # now the asset that was created should be there newasset = snapshot.Assets.TryGet(self.asset_create_id) self.assertIsNotNone(newasset) self.assertEqual(newasset.AssetType, 1) self.assertEqual(newasset.Precision, 8) self.assertEqual(Crypto.ToAddress(newasset.Admin), self.asset_admin) self.assertEqual(Crypto.ToAddress(newasset.Issuer), self.asset_admin) self.assertIsInstance(newasset.AssetId, UInt256) self.assertEqual(newasset.AssetId.ToBytes(), self.asset_create_id)
def GetAddress(self): """ Returns the public NEO address for this KeyPair Returns: str: The private key """ script = b'21' + self.PublicKey.encode_point(True) + b'ac' script_hash = Crypto.ToScriptHash(script) address = Crypto.ToAddress(script_hash) return address
def ScriptHash(self): if self._scriptHash is None: try: self._scriptHash = Crypto.ToScriptHash(self.Script) except binascii.Error: self._scriptHash = Crypto.ToScriptHash(self.Script, unhex=False) except Exception as e: logger.error("Could not create script hash: %s " % e) return self._scriptHash
def test_normal_signing(self): # test the normal order of operations: Keypair will initialize secp256r1 Elliptic curve parameters message = binascii.hexlify(b'Hello World') key = KeyPair( bytes.fromhex( '8631cd2635c416ba5f043561e9d2ff40b79c3bb2eb245e176615298b8372d0a4' )) signature = Crypto.Sign( message, '8631cd2635c416ba5f043561e9d2ff40b79c3bb2eb245e176615298b8372d0a4') self.assertTrue( Crypto.VerifySignature(message, signature, key.PublicKey)) TestSigningWithoutCryptoInstance.sig1 = signature.hex()
def test_script_hash(self): # Expected output taken from running: getHash(Buffer.from('abc', 'utf8')).toString('hex') # using https://github.com/CityOfZion/neon-wallet-react-native/blob/master/app/api/crypto/index.js expected_result = b'bb1be98c142444d7a56aa3981c3942a978e4dc33' result = Crypto.Default().Hash160(b'abc') self.assertEqual(expected_result, binascii.hexlify(result))
def ToScriptHash(self, address): """ Retrieve the script_hash based from an address. Args: address (str): a base58 encoded address. Raises: ValuesError: if an invalid address is supplied or the coin version is incorrect Exception: if the address string does not start with 'A' or the checksum fails Returns: UInt160: script hash. """ if len(address) == 34: if address[0] == 'A': data = b58decode(address) if data[0] != self.AddressVersion: raise ValueError('Not correct Coin Version') checksum = Crypto.Default().Hash256(data[:21])[:4] if checksum != data[21:]: raise Exception('Address format error') return UInt160(data=data[1:21]) else: raise Exception('Address format error') else: raise ValueError('Not correct Address, wrong length.')
def Blockchain_GetAccount(self, engine: ExecutionEngine): hash = UInt160(data=engine.CurrentContext.EvaluationStack.Pop().GetByteArray()) address = Crypto.ToAddress(hash).encode('utf-8') account = self.Accounts.GetOrAdd(address, new_instance=AccountState(script_hash=hash)) engine.CurrentContext.EvaluationStack.PushT(StackItem.FromInterface(account)) return True
def GenesisBlock() -> Block: """ Create the GenesisBlock. Returns: BLock: """ prev_hash = UInt256(data=bytearray(32)) timestamp = int( datetime(2016, 7, 15, 15, 8, 21, tzinfo=pytz.utc).timestamp()) index = 0 consensus_data = 2083236893 # Pay tribute To Bitcoin next_consensus = Blockchain.GetConsensusAddress( Blockchain.StandbyValidators()) script = Witness(bytearray(0), bytearray(PUSHT)) mt = MinerTransaction() mt.Nonce = 2083236893 output = TransactionOutput( Blockchain.SystemShare().Hash, Blockchain.SystemShare().Amount, Crypto.ToScriptHash( Contract.CreateMultiSigRedeemScript( int(len(Blockchain.StandbyValidators()) / 2) + 1, Blockchain.StandbyValidators()))) it = IssueTransaction([], [output], [], [script]) return Block( prev_hash, timestamp, index, consensus_data, next_consensus, script, [mt, Blockchain.SystemShare(), Blockchain.SystemCoin(), it], True)
def ToJson(self): """ Convert object members to a dictionary that can be parsed as JSON. Returns: dict: """ jsn = super(RegisterTransaction, self).ToJson() asset = { 'type': self.AssetType, 'name': self.Name, 'amount': self.Amount.value, 'precision': self.Precision if type(self.Precision) is int else self.Precision.decode('utf-8'), 'owner': self.Owner.ToString(), 'admin': Crypto.ToAddress(self.Admin) } jsn['asset'] = asset return jsn
def Storage_Delete(self, engine: ExecutionEngine): context = engine.CurrentContext.EvaluationStack.Pop().GetInterface() if not self.CheckStorageContext(context): return False key = engine.CurrentContext.EvaluationStack.Pop().GetByteArray() storage_key = StorageKey(script_hash=context.ScriptHash, key=key) keystr = key if len(key) == 20: keystr = Crypto.ToAddress(UInt160(data=key)) self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.STORAGE_DELETE, ContractParameter(ContractParameterType.String, keystr), context.ScriptHash, Blockchain.Default().Height + 1, engine.ScriptContainer.Hash if engine.ScriptContainer else None, test_mode=engine.testMode)) self._storages.Remove(storage_key.ToArray()) return True
def IsWalletTransaction(self, tx): """ Verifies if a transaction belongs to the wallet. Args: tx (TransactionOutput):an instance of type neo.Core.TX.Transaction.TransactionOutput to verify. Returns: bool: True, if transaction belongs to wallet. False, if not. """ for key, contract in self._contracts.items(): for output in tx.outputs: if output.ScriptHash.ToBytes() == contract.ScriptHash.ToBytes( ): return True for script in tx.scripts: if script.VerificationScript: if bytes(contract.Script) == script.VerificationScript: return True for watch_script_hash in self._watch_only: for output in tx.outputs: if output.ScriptHash == watch_script_hash: return True for script in tx.scripts: if Crypto.ToScriptHash(script.VerificationScript, unhex=False) == watch_script_hash: return True return False
def PrivateKeyFromWIF(wif): """ Get the private key from a WIF key Args: wif (str): The wif key Returns: bytes: The private key Raises: ValueError: if the input `wif` length != 52 if the input `wif` has an invalid format if the input `wif` has an invalid checksum """ if wif is None or len(wif) is not 52: raise ValueError( 'Please provide a wif with a length of 52 bytes (LEN: {0:d})'. format(len(wif))) data = base58.b58decode(wif) length = len(data) if length is not 38 or data[0] is not 0x80 or data[33] is not 0x01: raise ValueError("Invalid format!") checksum = Crypto.Hash256(data[0:34])[0:4] if checksum != data[34:]: raise ValueError("Invalid WIF Checksum!") return data[1:33]
def __init__(self, trigger_type, container, table, service, gas, testMode=False, exit_on_error=False): super(ApplicationEngine, self).__init__(container=container, crypto=Crypto.Default(), table=table, service=service, exit_on_error=exit_on_error) self.Trigger = trigger_type self.gas_amount = self.gas_free + gas.value self.testMode = testMode self._is_stackitem_count_strict = True
def Address(self): """ Get the accounts public address. Returns: str: base58 encoded string representing the account address. """ return Crypto.ToAddress(self.ScriptHash)
def Address(self): """ Get the public address of the transaction. Returns: str: base58 encoded string representing the address. """ return Crypto.ToAddress(self.ScriptHash)
def test_sign_before_KeyPair(self): # test signing prior to initializing secp256r1 Elliptic curve parameters with Keypair message = binascii.hexlify(b'Hello World') signature = Crypto.Sign( message, '8631cd2635c416ba5f043561e9d2ff40b79c3bb2eb245e176615298b8372d0a4') key = KeyPair( bytes.fromhex( '8631cd2635c416ba5f043561e9d2ff40b79c3bb2eb245e176615298b8372d0a4' )) self.assertTrue( Crypto.VerifySignature(message, signature, key.PublicKey)) TestSigningWithoutCryptoInstance.sig2 = signature.hex() # ensure the signatures are identical self.assertEqual(TestSigningWithoutCryptoInstance.sig1, TestSigningWithoutCryptoInstance.sig2)
def execute(self, arguments): wallet = PromptData.Wallet if len(arguments) < 3: print("Please specify the minimum required parameters") return False pubkey_in_wallet = arguments[0] if not PromptUtils.is_valid_public_key(pubkey_in_wallet): print("Invalid public key format") return False key_script_hash = Crypto.ToScriptHash(pubkey_in_wallet, unhex=True) if not wallet.ContainsKeyHash(key_script_hash): print("Supplied first public key does not exist in own wallet.") return False try: min_signature_cnt = int(arguments[1]) except ValueError: print(f"Invalid minimum signature count value: {arguments[1]}") return False if min_signature_cnt < 1: print("Minimum signatures count cannot be lower than 1") return False # validate minimum required signing key count signing_keys = arguments[2:] signing_keys.append(pubkey_in_wallet) len_signing_keys = len(signing_keys) if len_signing_keys < min_signature_cnt: # we need at least 2 public keys in total otherwise it's just a regular address. # 1 pub key is from an address in our own wallet, a secondary key can come from any place. print( f"Missing remaining signing keys. Minimum required: {min_signature_cnt} given: {len_signing_keys}" ) return False # validate remaining pub keys for key in signing_keys: if not PromptUtils.is_valid_public_key(key): print(f"Invalid signing key {key}") return False # validate that all signing keys are unique if len(signing_keys) > len(set(signing_keys)): print("Provided signing keys are not unique") return False verification_contract = Contract.CreateMultiSigContract( key_script_hash, min_signature_cnt, signing_keys) address = verification_contract.Address wallet.AddContract(verification_contract) print(f"Added multi-sig contract address {address} to wallet") return True
def test_faulty_message_param_to_verify_signature(self): faulty_message = bytes.fromhex( 'aa' ) # faulty because the message should be non-raw bytes. i.e. b'aa' fake_signature = bytes.fromhex('aabb') # irrelevant for the test fake_pubkey = bytes.fromhex('aabb') # irrelevant for the test result = Crypto.VerifySignature(faulty_message, fake_signature, fake_pubkey) self.assertFalse(result)
def is_valid_public_key(key): if len(key) != 66: return False try: Crypto.ToScriptHash(key, unhex=True) except Exception: # the UINT160 inside ToScriptHash can throw Exception return False else: return True
def Address(self): """ Get the wallet address associated with the coin. Returns: str: base58 encoded string representing the wallet address. """ if self._address is None: self._address = Crypto.ToAddress(self.Output.ScriptHash) return self._address
def ToScriptHash(scripts): """ Get a hash of the provided message using the ripemd160 algorithm. Args: scripts (str): message to hash. Returns: str: hash as a double digit hex string. """ return Crypto.Hash160(scripts)
def execute_test(data: dict): global test_count, skipped_test_count for test in data['tests']: test_count += 1 # interop service service = InteropService.InteropService() # message provider script_container = None message = test.get("message", None) if message: script_container = MessageProvider(message) # prepare script table script_table = None # there are currently no tests that load a script table so I don't know the format or key value they'll use # create engine and run engine = ExecutionEngine(crypto=Crypto.Default(), service=service, container=script_container, table=script_table, exit_on_error=True) # TODO: should enforce 0x<data> rule in the JSON test case if test['script'].startswith('0x'): script = test['script'][2:] else: script = test['script'] try: script = binascii.unhexlify(script) except binascii.Error: print(f"Skipping test {data['category']}-{data['name']}, cannot read script data") test_count -= 1 skipped_test_count += 1 continue engine.LoadScript(script) steps = test.get('steps', None) if steps is None: continue for i, step in enumerate(steps): actions = step.get('actions', []) for action in actions: if action == "StepInto": engine.StepInto() elif action == "Execute": engine.Execute() elif action == "StepOver": raise ValueError("StepOver not supported!") elif action == "StepOut": raise ValueError("StepOut not supported!") test_name = test.get("name", "") msg = f"{data['category']}-{data['name']}-{test_name}-{i}" assert_result(engine, step['result'], msg)
def ScriptHash(self): """ Get the script hash. Returns: UInt160: """ if self._scriptHash is None: self._scriptHash = Crypto.ToScriptHash(self.Script, unhex=False) return self._scriptHash
def test_neon_sig(self): key = KeyPair(priv_key=self.nmpk) hhex = hashlib.sha256(binascii.unhexlify(self.nmsg)).hexdigest() self.assertEqual(hhex, self.hashhex) sig = Crypto.Sign(self.nmsg, key.PrivateKey) self.assertEqual(sig.hex(), self.neon_sig)
def scripthash_to_address(scripthash): try: if scripthash[0:2] != "0x": # litle endian. convert to big endian now. print("Detected little endian scripthash. Converting to big endian for internal use.") scripthash_bytes = binascii.unhexlify(scripthash) scripthash = "0x%s" % binascii.hexlify(scripthash_bytes[::-1]).decode("utf-8") print("Big endian scripthash:", scripthash) return Crypto.ToAddress(UInt160.ParseString(scripthash)) except Exception as e: raise ConversionError("Wrong format")
def test_sign_and_verify_str(self): privkey = KeyPair.PrivateKeyFromWIF( "L44B5gGEpqEDRS9vVPz7QT35jcBG2r3CZwSwQ4fCewXAhAhqGVpP") keypair = KeyPair(privkey) hashdata = "74657374" keypair_signature = Crypto.Sign(hashdata, bytes(keypair.PrivateKey)) keypair_signature2 = Crypto.Default().Sign(hashdata, bytes(keypair.PrivateKey)) self.assertEqual(keypair_signature, keypair_signature2) # verify without unhexing verification_result = Crypto.VerifySignature("test", keypair_signature, keypair.PublicKey, unhex=False) verification_result2 = Crypto.Default().VerifySignature( "test", keypair_signature, keypair.PublicKey, unhex=False) self.assertEqual(verification_result, verification_result2) self.assertTrue(verification_result)
def ContainsKey(self, public_key): """ Test if the wallet contains the supplied public key. Args: public_key (edcsa.Curve.point): a public key to test for its existance. e.g. KeyPair.PublicKey Returns: bool: True if exists, False otherwise. """ return self.ContainsKeyHash( Crypto.ToScriptHash(public_key.encode_point(True), unhex=True))