diff --git a/lib/ckb/serializers/serializers.rb b/lib/ckb/serializers/serializers.rb index d9c75f2e..38991d4c 100644 --- a/lib/ckb/serializers/serializers.rb +++ b/lib/ckb/serializers/serializers.rb @@ -26,6 +26,8 @@ require_relative "out_point_serializer" require_relative "output_data_serializer" require_relative "raw_transaction_serializer" +require_relative "witness_serializer" +require_relative "transaction_serializer" module CKB module Serializers diff --git a/lib/ckb/serializers/transaction_serializer.rb b/lib/ckb/serializers/transaction_serializer.rb new file mode 100644 index 00000000..2c6494c9 --- /dev/null +++ b/lib/ckb/serializers/transaction_serializer.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module CKB + module Serializers + class TransactionSerializer + include TableSerializer + + # @param transaction [CKB::Types::Transaction] + def initialize(transaction) + @raw_serializer = RawTransactionSerializer.new(transaction) + @witnesses_serializer = DynVecSerializer.new(transaction.witnesses, WitnessSerializer) + @items_count = 2 + end + + private + + attr_reader :raw_serializer, :witnesses_serializer, :items_count + + def body + raw_layout + witnesses_layout + end + + def offsets + offset0 = (items_count + 1) * UINT32_CAPACITY + offset1 = offset0 + raw_capacity + + [offset0, offset1] + end + + def raw_layout + raw_serializer.serialize[2..-1] + end + + def raw_capacity + raw_serializer.capacity + end + + def witnesses_layout + witnesses_serializer.serialize[2..-1] + end + end + end +end diff --git a/lib/ckb/serializers/witness_serializer.rb b/lib/ckb/serializers/witness_serializer.rb new file mode 100644 index 00000000..883b9f6c --- /dev/null +++ b/lib/ckb/serializers/witness_serializer.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module CKB + module Serializers + class WitnessSerializer + include BaseSerializer + + # @param witness [String] + def initialize(witness) + witness ||= "" + witness = witness.start_with?("0x") ? witness[2..-1] : witness + items = witness.scan(/../) + @bytes_serializer = FixVecSerializer.new(items, ByteSerializer) + end + + private + + attr_reader :bytes_serializer + + def layout + bytes_serializer.serialize[2..-1] + end + end + end +end diff --git a/lib/ckb/types/transaction.rb b/lib/ckb/types/transaction.rb index 0cfe22f2..1d65ddf4 100644 --- a/lib/ckb/types/transaction.rb +++ b/lib/ckb/types/transaction.rb @@ -114,6 +114,11 @@ def compute_hash blake2b.hexdigest end + def size + transaction_serializer = CKB::Serializers::TransactionSerializer.new(self) + Utils.hex_to_bin(transaction_serializer.serialize).bytesize + 4 + end + def self.from_h(hash) return if hash.nil?