Class: CITA::TransactionSigner
- Inherits:
-
Object
- Object
- CITA::TransactionSigner
- Defined in:
- lib/cita/transaction_signer.rb
Class Method Summary collapse
-
.decode(tx_content, recover: true) ⇒ Hash
decode and parse bytes to hex string.
-
.encode(transaction, private_key) ⇒ Object
sign transaction.
-
.original_decode(tx_content, recover: true) ⇒ Hash
decode and support forks.
-
.sender_info(unverified_transaction) ⇒ Hash
get sender info (from address & public key).
-
.simple_decode(tx_content, recover: true) ⇒ Object
decode transaction, CITA v0.21 returns the ‘from` address in `getTransaction` RPC call so you can not to recover `from` address from context.
Class Method Details
.decode(tx_content, recover: true) ⇒ Hash
decode and parse bytes to hex string
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/cita/transaction_signer.rb', line 120 def decode(tx_content, recover: true) data = original_decode(tx_content, recover: recover) utx = data[:unverified_transaction] tx = utx[:transaction] version = tx[:version] tx[:value] = Utils.from_bytes(tx[:value]) tx[:data] = Utils.from_bytes(tx[:data]) tx[:nonce] = Utils.add_prefix_for_not_blank(tx[:nonce]) utx[:signature] = Utils.from_bytes(utx[:signature]) if version == 0 # rubocop:disable Style/NumericPredicate tx.delete(:to_v1) tx.delete(:chain_id_v1) tx[:to] = Utils.add_prefix_for_not_blank(tx[:to]) elsif [1, 2].include? version tx[:to] = Utils.from_bytes(tx[:to]) tx[:chain_id] = Utils.from_bytes(tx[:chain_id]) end data end |
.encode(transaction, private_key) ⇒ Object
sign transaction
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 |
# File 'lib/cita/transaction_signer.rb', line 13 def encode(transaction, private_key) tx = CITA::Protos::Transaction.new to = CITA::Utils.remove_hex_prefix(transaction.to)&.downcase tx.nonce = transaction.nonce tx.quota = transaction.quota tx.data = CITA::Utils.to_bytes(transaction.data) tx.value = hex_to_bytes(transaction.value) tx.version = transaction.version tx.valid_until_block = transaction.valid_until_block if transaction.version.zero? tx.to = to unless to.nil? tx.chain_id = transaction.chain_id elsif transaction.version == 1 || transaction.version == 2 tx.to_v1 = Utils.to_bytes(to) unless to.nil? tx.chain_id_v1 = hex_to_bytes(transaction.chain_id) end encoded_tx = Protos::Transaction.encode(tx) private_key_bytes = CITA::Utils.to_bytes(private_key) protobuf_hash = Utils.keccak256(encoded_tx) signature = Ciri::Crypto.ecdsa_signature(private_key_bytes, protobuf_hash).signature unverified_tx = Protos::UnverifiedTransaction.new(transaction: tx, signature: signature) encoded_unverified_tx = Protos::UnverifiedTransaction.encode(unverified_tx) CITA::Utils.from_bytes(encoded_unverified_tx) end |
.original_decode(tx_content, recover: true) ⇒ Hash
decode and support forks
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/cita/transaction_signer.rb', line 96 def original_decode(tx_content, recover: true) data = simple_decode(tx_content, recover: recover) utx = data[:unverified_transaction] tx = utx[:transaction] version = tx[:version] if version == 0 # rubocop:disable Style/NumericPredicate tx.delete(:to_v1) tx.delete(:chain_id_v1) elsif [1, 2].include? version tx[:to] = tx.delete(:to_v1) tx[:chain_id] = tx.delete(:chain_id_v1) else raise Transaction::VersionError, "transaction version error, expected 0, 1 or 2, got #{version}" end data end |
.sender_info(unverified_transaction) ⇒ Hash
get sender info (from address & public key)
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/cita/transaction_signer.rb', line 52 def sender_info(unverified_transaction) signature = unverified_transaction["signature"] transaction = unverified_transaction["transaction"] msg = Protos::Transaction.encode(transaction) msg_hash = CITA::Utils.keccak256(msg) pubkey = Ciri::Crypto.ecdsa_recover(msg_hash, signature) pubkey_hex = Utils.from_bytes(pubkey[1..-1]) from_address = Utils.keccak256(pubkey[1..-1])[-20..-1] from_address_hex = Utils.from_bytes(from_address) { address: from_address_hex, public_key: pubkey_hex } end |
.simple_decode(tx_content, recover: true) ⇒ Object
decode transaction, CITA v0.21 returns the ‘from` address in `getTransaction` RPC call so you can not to recover `from` address from context
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/cita/transaction_signer.rb', line 75 def simple_decode(tx_content, recover: true) content_bytes = CITA::Utils.to_bytes(tx_content) unverified_transaction = Protos::UnverifiedTransaction.decode(content_bytes) info = { unverified_transaction: unverified_transaction.to_h } if recover sender = sender_info(unverified_transaction) info[:sender] = sender end info end |