From 6547068cce6a70035b0d60d7311024ee8ceabe9c Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Fri, 22 Mar 2019 00:47:57 +0000 Subject: [PATCH 1/4] refactor: Script structure refactoring --- README.md | 63 ++++--------- lib/ckb/always_success_wallet.rb | 35 ++++--- lib/ckb/api.rb | 4 +- lib/ckb/udt_wallet.rb | 153 ++++++++++++++----------------- lib/ckb/utils.rb | 73 ++++++--------- lib/ckb/wallet.rb | 141 ++++++++++++++-------------- scripts | 2 +- 7 files changed, 204 insertions(+), 267 deletions(-) diff --git a/README.md b/README.md index a624708..9fc974d 100644 --- a/README.md +++ b/README.md @@ -12,21 +12,7 @@ If you don't want to build mruby-contracts yourself, we have a prebuilt binary a First, follow the [README](https://github.com/nervosnetwork/ckb/blob/develop/README.md) steps to make sure CKB is up and running. -There's only one required step you need to perform: make sure the miner process is using the correct type hash. To do this, first make sure you are in CKB's repo directory, and use the following command: - -```bash -$ ./target/release/ckb cli type_hash -0x8954a4ac5e5c33eb7aa8bb91e0a000179708157729859bd8cf7e2278e1e12980 -``` - -Note that you might need to adjust this command if: - -1. You are building debug version instead of release version -2. You use a custom config file. - -Then locate `default.toml` file in your config directory, navigate to miner section, change `type_hash` field to the value you get in the above command. Notice you will need to restart miner process after this change. - -There're also optional steps here which would help you when you are using the SDK but not required: +There're optional steps here which would help you when you are using the SDK but not required: ### Use Dummy POW mode @@ -87,22 +73,11 @@ In the Ruby shell, we can start playing with the SDK. ### Install mruby contract -First, we will need the `argv_source_entry` file as mentioned in `Prerequisite` section and preprocess it a bit. The following steps assume that the file and the processed file are all in directory `/path/to/`: - -```bash -$ git clone https://github.com/nervosnetwork/ckb-binary-to-script -$ cd ckb-binary-to-script -$ cargo build -$ ./target/debug/ckb-binary-to-script < /path/to/argv_source_entry > /path/to/processed_argv_source_entry -``` - -Notice this preprocessing step is only needed since Ruby doesn't have a FlatBuffers implementation, for another language, we can build this preprocessing step directly in the SDK. - -Then we can install this mruby contract into CKB: +We will need the `argv_source_entry` file as mentioned in `Prerequisite` section, then we can install this mruby contract into CKB: ```ruby [1] pry(main)> asw = Ckb::AlwaysSuccessWallet.new(api) -[2] pry(main)> conf = asw.install_mruby_cell!("/path/to/processed_argv_source_entry") +[2] pry(main)> conf = asw.install_mruby_cell!("/path/to/argv_source_entry") => {:out_point=>{:hash=>"0x20b849ffe67eb5872eca0d68fff1de193f07354ea903948ade6a3c170d89e282", :index=>0}, :cell_hash=>"0x03dba46071a6702b39c1e626f469b4ed9460ed0ad92cf2e21456c34e1e2b04fd"} [3] pry(main)> asw.configuration_installed?(conf) @@ -135,7 +110,7 @@ To play with wallets, first we need to add some capacities to a wallet: [1] pry(main)> bob = Ckb::Wallet.from_hex(api, "e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3") [2] pry(main)> bob.get_balance => 0 -[3] pry(main)> asw.send_capacity(bob.address, 100000) +[3] pry(main)> asw.send_capacity(bob.lock, 100000) [4] pry(main)> # wait a while [5] pry(main)> bob.get_balance => 100000 @@ -150,7 +125,7 @@ Now we can perform normal transfers between wallets: => 100000 [4] pry(main)> alice.get_balance => 0 -[5] pry(main)> bob.send_capacity(alice.address, 12345) +[5] pry(main)> bob.send_capacity(alice.lock, 12345) => "0xd7abc1407eb07d334fea86ef0e9b12b2273833137327c2a53f2d8ba1be1e4d85" [6] pry(main)> # wait for some time [7] pry(main)> alice.get_balance @@ -171,12 +146,6 @@ Ruby SDK here provides an easy way to create a token from an existing wallet ```bash [1] pry(main)> bob = Ckb::Wallet.from_hex(api, "e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3") [2] pry(main)> alice = Ckb::Wallet.from_hex(api, "76e853efa8245389e33f6fe49dcbd359eb56be2f6c3594e12521d2a806d32156") -[3] pry(main)> token_info = bob.created_token_info("Token 1") -=> # -[4] pry(main)> # token info represents the meta data for a token -[5] pry(main)> # we can assemble a wallet for user defined token with token info structure -[6] pry(main)> bob_token1 = bob.udt_wallet(token_info) -[7] pry(main)> alice_token1 = alice.udt_wallet(token_info) ``` Now we can create this token from a user with CKB capacities(since the cell used to hold the tokens will take some capacity): @@ -185,10 +154,16 @@ Now we can create this token from a user with CKB capacities(since the cell used [9] pry(main)> bob.get_balance => 87655 [10] pry(main)> # here we are creating 10000000 tokens for "Token 1", we put those tokens in a cell with 10000 CKB capacity -[11] pry(main)> bob.create_udt_token(10000, "Token 1", 10000000) -[12] pry(main)> bob_token1.get_balance +[11] pry(main)> result = bob.create_udt_token(10000, "Token 1", 10000000) +[12] pry(main)> token_info = result.token_info +=> # +[13] pry(main)> # token info represents the meta data for a token +[14] pry(main)> # we can assemble a wallet for user defined token with token info structure +[15] pry(main)> bob_token1 = bob.udt_wallet(token_info) +[16] pry(main)> alice_token1 = alice.udt_wallet(token_info) +[17] pry(main)> bob_token1.get_balance => 10000000 -[13] pry(main)> alice_token1.get_balance +[18] pry(main)> alice_token1.get_balance => 0 ``` @@ -216,10 +191,10 @@ The following code fulfills this step: ```bash [1] pry(main)> bob = Ckb::Wallet.from_hex(api, "e79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3") [2] pry(main)> alice = Ckb::Wallet.from_hex(api, "76e853efa8245389e33f6fe49dcbd359eb56be2f6c3594e12521d2a806d32156") -[3] pry(main)> token_info2 = bob.created_token_info("Token 2", account_wallet: true) -[4] pry(main)> bob_cell_token2 = bob.udt_account_wallet(token_info2) -[5] pry(main)> alice_cell_token2 = alice.udt_account_wallet(token_info2) -[6] pry(main)> bob.create_udt_token(10000, "Token 2", 10000000, account_wallet: true) +[3] pry(main)> result = bob.create_udt_token(10000, "Token 2", 10000000, account_wallet: true) +[4] pry(main)> token_info2 = result.token_info +[5] pry(main)> bob_cell_token2 = bob.udt_account_wallet(token_info2) +[6] pry(main)> alice_cell_token2 = alice.udt_account_wallet(token_info2) [7] pry(main)> alice.create_udt_account_wallet_cell(3010, token_info2) [8] pry(main)> bob_cell_token2.send_tokens(12345, alice_cell_token2) [9] pry(main)> bob_cell_token2.get_balance @@ -239,7 +214,7 @@ We have also designed a user defined token with a fixed upper cap. For this type [2] pry(main)> alice = Ckb::Wallet.from_hex(api, "76e853efa8245389e33f6fe49dcbd359eb56be2f6c3594e12521d2a806d32156") # Create a genesis UDT cell with 10000 capacity, the UDT has a fixed amount of 10000000. # The initial exchange rate is 1 capacity for 5 tokens. -[3] pry(main)> result = alice.create_fixed_amount_token(10000, 10000000, 5) +[3] pry(main)> result = bob.create_fixed_amount_token(10000, 10000000, 5) [4] pry(main)> fixed_token_info = result.token_info # Creates a UDT wallet that uses only one cell, the cell has a capacity of 11111 [5] pry(main)> alice.create_udt_account_wallet_cell(11111, fixed_token_info) diff --git a/lib/ckb/always_success_wallet.rb b/lib/ckb/always_success_wallet.rb index 1083774..45f320a 100644 --- a/lib/ckb/always_success_wallet.rb +++ b/lib/ckb/always_success_wallet.rb @@ -10,7 +10,7 @@ def initialize(api) @api = api end - def send_capacity(target_address, capacity) + def send_capacity(target_lock, capacity) i = gather_inputs(capacity, MIN_CELL_CAPACITY) input_capacities = i.capacities @@ -18,32 +18,33 @@ def send_capacity(target_address, capacity) { capacity: capacity, data: "", - lock: target_address + lock: target_lock } ] if input_capacities > capacity outputs << { capacity: input_capacities - capacity, data: "", - lock: self.address + lock: lock_script_json_object } end tx = { version: 0, deps: [api.always_success_out_point], inputs: i.inputs, - outputs: outputs + outputs: outputs, + embeds: [] } api.send_transaction(tx) end - def install_mruby_cell!(processed_mruby_cell_filename) - data = File.read(processed_mruby_cell_filename) + def install_mruby_cell!(mruby_cell_filename) + data = File.read(mruby_cell_filename) cell_hash = Ckb::Utils.bin_to_prefix_hex(Ckb::Blake2b.digest(data)) output = { capacity: 0, data: data, - lock: address + lock: lock_script_json_object } output[:capacity] = Ckb::Utils.calculate_cell_min_capacity(output) @@ -55,7 +56,7 @@ def install_mruby_cell!(processed_mruby_cell_filename) outputs << { capacity: input_capacities - output[:capacity], data: "", - lock: address + lock: lock_script_json_object } end @@ -63,7 +64,8 @@ def install_mruby_cell!(processed_mruby_cell_filename) version: 0, deps: [api.always_success_out_point], inputs: i.inputs, - outputs: outputs + outputs: outputs, + embeds: [] } hash = api.send_transaction(tx) { @@ -90,20 +92,15 @@ def get_balance get_unspent_cells.map { |c| c[:capacity] }.reduce(0, &:+) end - def address - unlock_type_hash - end - private - def unlock_type_hash - @__unlock_type_hash ||= Ckb::Utils.json_script_to_type_hash(unlock_script_json_object) + def lock_hash + @__lock_hash ||= Ckb::Utils.json_script_to_hash(lock_script_json_object) end - def unlock_script_json_object + def lock_script_json_object { version: 0, reference: api.always_success_cell_hash, - signed_args: [], args: [] } end @@ -114,7 +111,7 @@ def get_unspent_cells current_from = 1 while current_from <= to current_to = [current_from + 100, to].min - cells = api.get_cells_by_type_hash(unlock_type_hash, current_from, current_to) + cells = api.get_cells_by_lock_hash(lock_hash, current_from, current_to) results.concat(cells) current_from = current_to + 1 end @@ -134,7 +131,7 @@ def gather_inputs(capacity, min_capacity) hash: cell[:out_point][:hash], index: cell[:out_point][:index] }, - unlock: unlock_script_json_object + args: [] } inputs << input input_capacities += cell[:capacity] diff --git a/lib/ckb/api.rb b/lib/ckb/api.rb index 6768bcb..59c0eb4 100644 --- a/lib/ckb/api.rb +++ b/lib/ckb/api.rb @@ -98,9 +98,9 @@ def get_tip_block_number alias get_tip_number get_tip_block_number - def get_cells_by_type_hash(hash_hex, from, to) + def get_cells_by_lock_hash(hash_hex, from, to) params = [hash_hex, from, to] - rpc_request("get_cells_by_type_hash", params: params)[:result] + rpc_request("get_cells_by_lock_hash", params: params)[:result] end def get_transaction(tx_hash_hex) diff --git a/lib/ckb/udt_wallet.rb b/lib/ckb/udt_wallet.rb index 9379a1d..73c89af 100644 --- a/lib/ckb/udt_wallet.rb +++ b/lib/ckb/udt_wallet.rb @@ -24,58 +24,55 @@ def initialize(api, name, pubkey, account_wallet) @account_wallet = account_wallet end - def unlock_script_json_object(pubkey) + def lock_json_object(pubkey) { version: 0, reference: api.mruby_cell_hash, - signed_args: [ + args: [ account_wallet ? UNLOCK_SINGLE_CELL_SCRIPT : UNLOCK_SCRIPT, name, pubkey - ], - args: [] + ] } end - def contract_script_json_object + def type_json_object { version: 0, reference: api.mruby_cell_hash, - signed_args: [ + args: [ CONTRACT_SCRIPT, name, pubkey - ], - args: [] + ] } end def to_json { - api: api.uri.to_s, name: name, pubkey: pubkey, - account_wallet: account_wallet + account_wallet: account_wallet, }.to_json end - def self.from_json(json) + def self.from_json(api, json) o = JSON.parse(json, symbolize_names: true) - TokenInfo.new(Ckb::Api.new(host: o[:api]), o[:name], o[:pubkey], o[:account_wallet]) + TokenInfo.new(api, o[:name], o[:pubkey], o[:account_wallet]) end end class FixedAmountTokenInfo attr_reader :api attr_reader :input_hash - attr_reader :lock_hash + attr_reader :issuer_lock attr_reader :pubkey attr_reader :rate - def initialize(api, input_hash, lock_hash, pubkey, rate) + def initialize(api, input_hash, issuer_lock, pubkey, rate) @api = api @input_hash = input_hash - @lock_hash = lock_hash + @issuer_lock = issuer_lock @pubkey = pubkey @rate = rate end @@ -85,17 +82,19 @@ def account_wallet end def fetch_cell - hash = genesis_unlock_type_hash + hash = Ckb::Utils.json_script_to_hash(genesis_lock_json_object) to = api.get_tip_number results = [] current_from = 1 while current_from <= to current_to = [current_from + 100, to].min - cells = api.get_cells_by_type_hash(hash, current_from, current_to) + cells = api.get_cells_by_lock_hash(hash, current_from, current_to) cells_with_data = cells.map do |cell| tx = api.get_transaction(cell[:out_point][:hash]) amount = Ckb::Utils.hex_to_bin(tx[:outputs][cell[:out_point][:index]][:data]).unpack("Q<")[0] - cell.merge(amount: amount) + args = cell[:lock][:args].map { |arg| arg.pack("c*") } + lock = cell[:lock].merge(args: args) + cell.merge(amount: amount, lock: lock) end results.concat(cells_with_data) current_from = current_to + 1 @@ -106,76 +105,60 @@ def fetch_cell results[0] end - def genesis_unlock_type_hash - Ckb::Utils.json_script_to_type_hash(genesis_unlock_script_json_object) - end - - def genesis_unlock_script_json_object + def genesis_lock_json_object { version: 0, reference: api.mruby_cell_hash, - signed_args: [ + args: [ Ckb::FIXED_AMOUNT_GENESIS_UNLOCK_SCRIPT, + input_hash, rate.to_s, - lock_hash, + Ckb::Utils.json_script_to_hash(issuer_lock), pubkey - ], - args: [] + ] } end - def genesis_contract_script_json_object - { - version: 0, - reference: api.mruby_cell_hash, - signed_args: [ - Ckb::FIXED_AMOUNT_CONTRACT_SCRIPT, - input_hash, - pubkey - ], - args: [] - } + def genesis_type_json_object + type_json_object end - def unlock_script_json_object(pubkey) + def lock_json_object(pubkey) { version: 0, reference: api.mruby_cell_hash, - signed_args: [ + args: [ UNLOCK_SINGLE_CELL_SCRIPT, input_hash, pubkey - ], - args: [] + ] } end - def contract_script_json_object + def type_json_object { version: 0, reference: api.mruby_cell_hash, - signed_args: [ + args: [ Ckb::FIXED_AMOUNT_CONTRACT_SCRIPT, input_hash, pubkey - ], - args: [] + ] } end def to_json { - api: api.uri.to_s, input_hash: input_hash, - lock_hash: lock_hash, + issuer_lock: issuer_lock, pubkey: pubkey, rate: rate }.to_json end - def self.from_json(json) + def self.from_json(api, json) o = JSON.parse(json, symbolize_names: true) - FixedAmountTokenInfo.new(Ckb::Api.new(host: o[:api]), o[:input_hash], o[:lock_hash], o[:pubkey], o[:rate]) + FixedAmountTokenInfo.new(api, o[:input_hash], o[:issuer_lock], o[:pubkey], o[:rate]) end end @@ -203,16 +186,12 @@ def wallet Ckb::Wallet.new(api, privkey) end - def address - unlock_type_hash - end - - def unlock_type_hash - Ckb::Utils.json_script_to_type_hash(token_info.unlock_script_json_object(pubkey)) + def lock + token_info.lock_json_object(pubkey) end - def contract_type_hash - Ckb::Utils.json_script_to_type_hash(token_info.contract_script_json_object) + def lock_hash + Ckb::Utils.json_script_to_hash(token_info.lock_json_object(pubkey)) end def get_transaction(hash_hex) @@ -228,16 +207,14 @@ def pubkey_bin end def get_unspent_cells - hash = unlock_type_hash + hash = lock_hash to = api.get_tip_number results = [] current_from = 1 while current_from <= to current_to = [current_from + 100, to].min - cells = api.get_cells_by_type_hash(hash, current_from, current_to) - cells_with_data = cells.select do |cell| - cell[:lock] == address - end.map do |cell| + cells = api.get_cells_by_lock_hash(hash, current_from, current_to) + cells_with_data = cells.map do |cell| tx = get_transaction(cell[:out_point][:hash]) amount = Ckb::Utils.hex_to_bin(tx[:outputs][cell[:out_point][:index]][:data]).unpack("Q<")[0] cell.merge(amount: amount) @@ -257,16 +234,15 @@ def get_balance # Generate a partial tx which provides CKB coins in exchange for UDT tokens. # UDT sender should use +send_amount+ to fill in the other part def generate_partial_tx_for_udt_cell(token_amount, udt_cell_capacity, exchange_capacity) - output = generate_output(address, token_amount, udt_cell_capacity) + output = generate_output(lock, token_amount, udt_cell_capacity) wallet.sign_capacity_for_udt_cell(udt_cell_capacity + exchange_capacity, output) end def send_amount(amount, partial_tx) outputs = partial_tx[:outputs] inputs = partial_tx[:inputs].map do |input| - args = input[:unlock][:args] + [outputs.length.times.to_a.join(",")] - unlock = input[:unlock].merge(args: args) - input.merge(unlock: unlock) + args = input[:args] + [outputs.length.times.to_a.join(",")] + input.merge(args: args) end i = gather_inputs(amount) @@ -284,21 +260,21 @@ def send_amount(amount, partial_tx) outputs << { capacity: i.capacities, data: [i.amounts - amount].pack("Q<"), - lock: address, - type: token_info.contract_script_json_object + lock: lock, + type: token_info.type_json_object } if spare_cell_capacity > MIN_CELL_CAPACITY outputs << { capacity: spare_cell_capacity, data: "", - lock: wallet.address + lock: wallet.lock } end else outputs << { capacity: i.capacities + spare_cell_capacity, data: "", - lock: wallet.address + lock: wallet.lock } end @@ -307,7 +283,8 @@ def send_amount(amount, partial_tx) version: 0, deps: [api.mruby_out_point], inputs: inputs + self_inputs, - outputs: outputs + outputs: outputs, + embeds: [] } api.send_transaction(tx) end @@ -323,7 +300,7 @@ def merge_cells hash: cell[:out_point][:hash], index: cell[:out_point][:index] }, - unlock: token_info.unlock_script_json_object(pubkey) + unlock: token_info.lock_json_object(pubkey) } inputs << input input_capacity += cell[:capacity] @@ -334,7 +311,7 @@ def merge_cells capacity: total_capacity, data: [total_amount].pack("Q<"), lock: wallet.udt_cell_wallet(token_info).address, - type: token_info.contract_script_json_object + type: token_info.type_json_object } ] tx = { @@ -347,12 +324,12 @@ def merge_cells end private - def generate_output(udt_address, amount, capacity) + def generate_output(udt_lock, amount, capacity) output = { capacity: capacity, data: [amount].pack("Q<"), - lock: udt_address, - type: token_info.contract_script_json_object + lock: udt_lock, + type: token_info.type_json_object } min_capacity = Ckb::Utils.calculate_cell_min_capacity(output) @@ -373,7 +350,7 @@ def gather_inputs(amount) hash: cell[:out_point][:hash], index: cell[:out_point][:index] }, - unlock: token_info.unlock_script_json_object(pubkey) + args: [] } inputs << input input_capacities += cell[:capacity] @@ -409,7 +386,12 @@ def fetch_cell when 0 raise "Please create udt cell wallet first!" when 1 - cells[0] + cell = cells[0] + args = cell[:lock][:args].map do |arg| + arg.pack("c*") + end + lock = cell[:lock].merge(args: args) + cell.merge(lock: lock) else raise "There's more than one cell for this UDT! You can use merge_cells in UdtWallet to merge them into one" end @@ -429,21 +411,21 @@ def send_tokens(amount, target_wallet) hash: cell[:out_point][:hash], index: cell[:out_point][:index] }, - unlock: token_info.unlock_script_json_object(pubkey) + args: [] } ] outputs = [ { capacity: cell[:capacity], data: [cell[:amount] - amount].pack("Q<"), - lock: address, - type: token_info.contract_script_json_object + lock: lock, + type: token_info.type_json_object }, { capacity: target_cell[:capacity], data: [target_cell[:amount] + amount].pack("Q<"), lock: target_cell[:lock], - type: token_info.contract_script_json_object + type: token_info.type_json_object } ] signed_inputs = Ckb::Utils.sign_sighash_all_anyonecanpay_inputs(inputs, outputs, privkey) @@ -453,13 +435,14 @@ def send_tokens(amount, target_wallet) hash: target_cell[:out_point][:hash], index: target_cell[:out_point][:index] }, - unlock: target_wallet.token_info.unlock_script_json_object(target_wallet.pubkey), + args: [] } tx = { version: 0, deps: [api.mruby_out_point], inputs: signed_inputs + [target_input], - outputs: outputs + outputs: outputs, + embeds: [] } api.send_transaction(tx) end diff --git a/lib/ckb/utils.rb b/lib/ckb/utils.rb index b07f4bf..6ad0200 100644 --- a/lib/ckb/utils.rb +++ b/lib/ckb/utils.rb @@ -1,3 +1,4 @@ +# coding: utf-8 require "secp256k1" module Ckb @@ -24,16 +25,12 @@ def self.extract_pubkey_bin(privkey_bin) Secp256k1::PrivateKey.new(privkey: privkey_bin).pubkey.serialize end - def self.json_script_to_type_hash(script) + def self.json_script_to_hash(script) s = Ckb::Blake2b.new if script[:reference] s << hex_to_bin(script[:reference]) end - s << "|" - if script[:binary] - s << script[:binary] - end - (script[:signed_args] || []).each do |arg| + (script[:args] || []).each do |arg| s << arg end bin_to_prefix_hex(s.digest) @@ -47,12 +44,11 @@ def self.sign_sighash_multiple_anyonecanpay_inputs(inputs, outputs, privkey) s.update(sighash_type) s.update(Ckb::Utils.hex_to_bin(input[:previous_output][:hash])) s.update(input[:previous_output][:index].to_s) - s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(input[:unlock]))) outputs.each do |output| s.update(output[:capacity].to_s) - s.update(Ckb::Utils.hex_to_bin(output[:lock])) + s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(output[:lock]))) if output[:type] - s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(output[:type]))) + s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(output[:type]))) end end @@ -60,8 +56,8 @@ def self.sign_sighash_multiple_anyonecanpay_inputs(inputs, outputs, privkey) signature_hex = Ckb::Utils.bin_to_hex(signature) # output(s) will be filled when assembling the transaction - unlock = input[:unlock].merge(args: [signature_hex, sighash_type]) - input.merge(unlock: unlock) + args = input[:args] + [signature_hex, sighash_type] + input.merge(args: args) end end @@ -73,20 +69,19 @@ def self.sign_sighash_all_anyonecanpay_inputs(inputs, outputs, privkey) s.update(sighash_type) s.update(Ckb::Utils.hex_to_bin(input[:previous_output][:hash])) s.update(input[:previous_output][:index].to_s) - s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(input[:unlock]))) outputs.each do |output| s.update(output[:capacity].to_s) - s.update(Ckb::Utils.hex_to_bin(output[:lock])) + s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(output[:lock]))) if output[:type] - s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(output[:type]))) + s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(output[:type]))) end end signature = key.ecdsa_serialize(key.ecdsa_sign(s.digest, raw: true)) signature_hex = Ckb::Utils.bin_to_hex(signature) - unlock = input[:unlock].merge(args: [signature_hex, sighash_type]) - input.merge(unlock: unlock) + args = input[:args] + [signature_hex, sighash_type] + input.merge(args: args) end end @@ -97,13 +92,12 @@ def self.sign_sighash_all_inputs(inputs, outputs, privkey) inputs.each do |input| s.update(Ckb::Utils.hex_to_bin(input[:previous_output][:hash])) s.update(input[:previous_output][:index].to_s) - s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(input[:unlock]))) end outputs.each do |output| s.update(output[:capacity].to_s) - s.update(Ckb::Utils.hex_to_bin(output[:lock])) + s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(output[:lock]))) if output[:type] - s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(output[:type]))) + s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(output[:type]))) end end key = Secp256k1::PrivateKey.new(privkey: privkey) @@ -111,23 +105,23 @@ def self.sign_sighash_all_inputs(inputs, outputs, privkey) signature_hex = Ckb::Utils.bin_to_hex(signature) inputs.map do |input| - unlock = input[:unlock].merge(args: [signature_hex, sighash_type]) - input.merge(unlock: unlock) + args = input[:args] + [signature_hex, sighash_type] + input.merge(args: args) + end + end + + def self.calculate_script_capacity(script) + capacity = 1 + (script[:args] || []).map { |arg| arg.bytesize }.reduce(0, &:+) + if script[:reference] + capacity += Ckb::Utils.hex_to_bin(script[:reference]).bytesize end + capacity end def self.calculate_cell_min_capacity(output) - capacity = 8 + output[:data].bytesize + Ckb::Utils.hex_to_bin(output[:lock]).bytesize + capacity = 8 + output[:data].bytesize + calculate_script_capacity(output[:lock]) if type = output[:type] - capacity += 1 - capacity += (type[:args] || []).map { |arg| arg.bytesize }.reduce(0, &:+) - if type[:reference] - capacity += Ckb::Utils.hex_to_bin(type[:reference]).bytesize - end - if type[:binary] - capacity += type[:binary].bytesize - end - capacity += (type[:signed_args] || []).map { |arg| arg.bytesize }.reduce(0, &:+) + capacity += calculate_script_capacity(type) end capacity end @@ -137,29 +131,20 @@ def self.calculate_cell_min_capacity(output) # have to do type conversions here. def self.normalize_tx_for_json!(transaction) transaction[:inputs].each do |input| - input[:unlock][:args] = input[:unlock][:args].map do |arg| + input[:args] = input[:args].map do |arg| Ckb::Utils.bin_to_prefix_hex(arg) end - input[:unlock][:signed_args] = input[:unlock][:signed_args].map do |arg| - Ckb::Utils.bin_to_prefix_hex(arg) - end - if input[:unlock][:binary] - input[:unlock][:binary] = Ckb::Utils.bin_to_prefix_hex(input[:unlock][:binary]) - end end transaction[:outputs].each do |output| output[:data] = Ckb::Utils.bin_to_prefix_hex(output[:data]) + output[:lock][:args] = output[:lock][:args].map do |arg| + Ckb::Utils.bin_to_prefix_hex(arg) + end if output[:type] output[:type][:args] = output[:type][:args].map do |arg| Ckb::Utils.bin_to_prefix_hex(arg) end - output[:type][:signed_args] = output[:type][:signed_args].map do |arg| - Ckb::Utils.bin_to_prefix_hex(arg) - end - if output[:type][:binary] - output[:type][:binary] = Ckb::Utils.bin_to_prefix_hex(output[:type][:binary]) - end end end transaction diff --git a/lib/ckb/wallet.rb b/lib/ckb/wallet.rb index caeae44..6ff4274 100644 --- a/lib/ckb/wallet.rb +++ b/lib/ckb/wallet.rb @@ -24,8 +24,8 @@ def initialize(api, privkey) @privkey = privkey end - def address - verify_type_hash + def lock + verify_script_json_object end def get_unspent_cells @@ -34,7 +34,7 @@ def get_unspent_cells current_from = 1 while current_from <= to current_to = [current_from + 100, to].min - cells = api.get_cells_by_type_hash(verify_type_hash, current_from, current_to) + cells = api.get_cells_by_lock_hash(verify_script_hash, current_from, current_to) results.concat(cells) current_from = current_to + 1 end @@ -45,7 +45,7 @@ def get_balance get_unspent_cells.map { |c| c[:capacity] }.reduce(0, &:+) end - def generate_tx(target_address, capacity) + def generate_tx(target_lock, capacity) i = gather_inputs(capacity, MIN_CELL_CAPACITY) input_capacities = i.capacities @@ -53,26 +53,27 @@ def generate_tx(target_address, capacity) { capacity: capacity, data: "", - lock: target_address + lock: target_lock } ] if input_capacities > capacity outputs << { capacity: input_capacities - capacity, data: "", - lock: self.address + lock: lock } end { version: 0, deps: [api.mruby_out_point], inputs: Ckb::Utils.sign_sighash_all_inputs(i.inputs, outputs, privkey), - outputs: outputs + outputs: outputs, + embeds: [] } end - def send_capacity(target_address, capacity) - tx = generate_tx(target_address, capacity) + def send_capacity(target_lock, capacity) + tx = generate_tx(target_lock, capacity) api.send_transaction(tx) end @@ -93,7 +94,7 @@ def sign_capacity_for_udt_cell(capacity_to_pay, token_output) outputs << { capacity: input_capacities - capacity_to_pay, data: "", - lock: self.address + lock: lock } end @@ -105,10 +106,6 @@ def sign_capacity_for_udt_cell(capacity_to_pay, token_output) } end - def created_token_info(token_name, account_wallet: false) - TokenInfo.new(api, token_name, Ckb::Utils.bin_to_hex(pubkey_bin), account_wallet) - end - # Create a new cell for storing an existing user defined token, you can # think this as an ethereum account for a user defined token def create_udt_account_wallet_cell(capacity, token_info) @@ -118,8 +115,8 @@ def create_udt_account_wallet_cell(capacity, token_info) cell = { capacity: capacity, data: [0].pack("Q<"), - lock: udt_account_wallet(token_info).address, - type: token_info.contract_script_json_object + lock: udt_account_wallet(token_info).lock, + type: token_info.type_json_object } needed_capacity = Ckb::Utils.calculate_cell_min_capacity(cell) if capacity < needed_capacity @@ -134,14 +131,15 @@ def create_udt_account_wallet_cell(capacity, token_info) outputs << { capacity: input_capacities - capacity, data: "", - lock: self.address + lock: self.lock } end tx = { version: 0, deps: [api.mruby_out_point], inputs: Ckb::Utils.sign_sighash_all_inputs(i.inputs, outputs, privkey), - outputs: outputs + outputs: outputs, + embeds: [] } hash = api.send_transaction(tx) # This is in fact an OutPoint here @@ -153,8 +151,8 @@ def create_udt_account_wallet_cell(capacity, token_info) # Create a user defined token with fixed upper amount, subsequent invocations # on this method will create different tokens. - def create_fixed_amount_token(capacity, tokens, rate, lock_hash: nil) - lock_hash ||= verify_type_hash + def create_fixed_amount_token(capacity, tokens, rate, lock: nil) + lock ||= verify_script_json_object i = gather_inputs(capacity, MIN_CELL_CAPACITY) input_capacities = i.capacities @@ -163,13 +161,12 @@ def create_fixed_amount_token(capacity, tokens, rate, lock_hash: nil) i.inputs.each do |input| ms.update(Ckb::Utils.hex_to_bin(input[:previous_output][:hash])) ms.update(input[:previous_output][:index].to_s) - ms.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(input[:unlock]))) end info = FixedAmountTokenInfo.new( api, Ckb::Utils.bin_to_hex(ms.digest), - lock_hash, + lock, Ckb::Utils.bin_to_hex(pubkey_bin), rate) @@ -178,46 +175,45 @@ def create_fixed_amount_token(capacity, tokens, rate, lock_hash: nil) { capacity: capacity, data: data, - lock: info.genesis_unlock_type_hash, - type: info.genesis_contract_script_json_object + lock: info.genesis_lock_json_object, + type: info.genesis_type_json_object } ] if input_capacities > capacity outputs << { capacity: input_capacities - capacity, data: "", - lock: self.address + lock: self.lock } end s = Ckb::Blake2b.new - contract_type_hash_bin = Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(outputs[0][:type])) - s.update(contract_type_hash_bin) + contract_hash_bin = Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(outputs[0][:type])) + s.update(contract_hash_bin) i.inputs.each do |input| s.update(Ckb::Utils.hex_to_bin(input[:previous_output][:hash])) s.update(input[:previous_output][:index].to_s) - s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_type_hash(input[:unlock]))) end s.update(outputs[0][:capacity].to_s) - s.update(Ckb::Utils.hex_to_bin(outputs[0][:lock])) - s.update(contract_type_hash_bin) + s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(outputs[0][:lock]))) + s.update(contract_hash_bin) s.update(data) if outputs[1] s.update(outputs[1][:capacity].to_s) - s.update(Ckb::Utils.hex_to_bin(outputs[1][:lock])) + s.update(Ckb::Utils.hex_to_bin(Ckb::Utils.json_script_to_hash(outputs[1][:lock]))) end key = Secp256k1::PrivateKey.new(privkey: privkey) signature = key.ecdsa_serialize(key.ecdsa_sign(s.digest, raw: true)) - signature_hex = Ckb::Utils.bin_to_hex(signature) - outputs[0][:type][:args] = [signature_hex] + outputs[0][:data] += signature tx = { version: 0, deps: [api.mruby_out_point], inputs: Ckb::Utils.sign_sighash_all_inputs(i.inputs, outputs, privkey), - outputs: outputs + outputs: outputs, + embeds: [] } hash = api.send_transaction(tx) OpenStruct.new(tx_hash: hash, token_info: info) @@ -228,7 +224,7 @@ def purchase_fixed_amount_token(tokens, token_info) paid_cell = { capacity: paid_capacity, data: "", - lock: token_info.lock_hash + lock: token_info.issuer_lock } needed_capacity = Ckb::Utils.calculate_cell_min_capacity(paid_cell) if paid_capacity < needed_capacity @@ -248,14 +244,14 @@ def purchase_fixed_amount_token(tokens, token_info) hash: wallet_cell[:out_point][:hash], index: wallet_cell[:out_point][:index] }, - unlock: token_info.unlock_script_json_object(pubkey) + args: [] }, { previous_output: { hash: udt_genesis_cell[:out_point][:hash], index: udt_genesis_cell[:out_point][:index] }, - unlock: token_info.genesis_unlock_script_json_object + args: [] } ] @@ -264,13 +260,13 @@ def purchase_fixed_amount_token(tokens, token_info) capacity: wallet_cell[:capacity], data: [wallet_cell[:amount] + tokens].pack("Q<"), lock: wallet_cell[:lock], - type: token_info.contract_script_json_object + type: token_info.type_json_object }, { capacity: udt_genesis_cell[:capacity], data: [udt_genesis_cell[:amount] - tokens].pack("Q<"), lock: udt_genesis_cell[:lock], - type: token_info.genesis_contract_script_json_object + type: token_info.genesis_type_json_object }, paid_cell ] @@ -278,7 +274,7 @@ def purchase_fixed_amount_token(tokens, token_info) outputs << { capacity: input_capacities - paid_capacity, data: "", - lock: self.address + lock: self.lock } end @@ -287,7 +283,8 @@ def purchase_fixed_amount_token(tokens, token_info) version: 0, deps: [api.mruby_out_point], inputs: signed_inputs + additional_inputs, - outputs: outputs + outputs: outputs, + embeds: [] } api.send_transaction(tx) end @@ -297,48 +294,40 @@ def create_udt_token(capacity, token_name, tokens, account_wallet: false) token_info = created_token_info(token_name, account_wallet: account_wallet) wallet = account_wallet ? udt_account_wallet(token_info) : udt_wallet(token_info) - i = gather_inputs(capacity, MIN_UDT_CELL_CAPACITY) - input_capacities = i.capacities - data = [tokens].pack("Q<") s = Ckb::Blake2b.new - s.update(Ckb::Utils.hex_to_bin(wallet.contract_type_hash)) s.update(data) key = Secp256k1::PrivateKey.new(privkey: privkey) signature = key.ecdsa_serialize(key.ecdsa_sign(s.digest, raw: true)) - signature_hex = Ckb::Utils.bin_to_hex(signature) - outputs = [ - { - capacity: capacity, - data: data, - lock: wallet.address, - type: { - version: 0, - args: [ - signature_hex - ], - reference: api.mruby_cell_hash, - signed_args: [ - Ckb::CONTRACT_SCRIPT, - token_info.name, - token_info.pubkey - ] - } - } - ] + i = gather_inputs(capacity, MIN_UDT_CELL_CAPACITY) + input_capacities = i.capacities + + udt_cell = { + capacity: capacity, + data: data + signature, + lock: wallet.lock, + type: token_info.type_json_object + } + min_capacity = Ckb::Utils.calculate_cell_min_capacity(udt_cell) + if capacity < min_capacity + raise "Capacity is not enough to hold the whole cell, minimal capacity: #{min_capacity}" + end + + outputs = [udt_cell] if input_capacities > capacity outputs << { capacity: input_capacities - capacity, data: "", - lock: self.address + lock: self.lock } end tx = { version: 0, deps: [api.mruby_out_point], inputs: Ckb::Utils.sign_sighash_all_inputs(i.inputs, outputs, privkey), - outputs: outputs + outputs: outputs, + embeds: [] } hash = api.send_transaction(tx) OpenStruct.new(tx_hash: hash, token_info: token_info) @@ -353,6 +342,10 @@ def udt_account_wallet(token_info) end private + def created_token_info(token_name, account_wallet: false) + TokenInfo.new(api, token_name, Ckb::Utils.bin_to_hex(pubkey_bin), account_wallet) + end + def gather_inputs(capacity, min_capacity) if capacity < min_capacity raise "capacity cannot be less than #{min_capacity}" @@ -366,7 +359,7 @@ def gather_inputs(capacity, min_capacity) hash: cell[:out_point][:hash], index: cell[:out_point][:index] }, - unlock: verify_script_json_object + args: [pubkey] } inputs << input input_capacities += cell[:capacity] @@ -388,21 +381,25 @@ def pubkey_bin Ckb::Utils.extract_pubkey_bin(privkey) end + def pubkey_hash_bin + Ckb::Blake2b.digest(Ckb::Blake2b.digest(pubkey_bin)) + end + def verify_script_json_object { version: 0, reference: api.mruby_cell_hash, - signed_args: [ + args: [ VERIFY_SCRIPT, # We could of course just hash raw bytes, but since right now CKB # CLI already uses this scheme, we stick to the same way for compatibility - Ckb::Utils.bin_to_hex(pubkey_bin) + Ckb::Utils.bin_to_hex(pubkey_hash_bin) ] } end - def verify_type_hash - @__verify_type_hash ||= Ckb::Utils.json_script_to_type_hash(verify_script_json_object) + def verify_script_hash + Ckb::Utils.json_script_to_hash(verify_script_json_object) end def self.random(api) diff --git a/scripts b/scripts index a75b5df..841e05b 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit a75b5df8fdf833b7316bbd9213f73436401c86a5 +Subproject commit 841e05ba9466e38fc81db562f56226d90aeb29f2 From 1d22fb04c957ae55b481c4a2a2cc2ae870a193a5 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Fri, 22 Mar 2019 05:59:21 +0000 Subject: [PATCH 2/4] rename: Rename reference to binary_hash in Script --- lib/ckb/always_success_wallet.rb | 2 +- lib/ckb/udt_wallet.rb | 10 +++++----- lib/ckb/utils.rb | 8 ++++---- lib/ckb/wallet.rb | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/ckb/always_success_wallet.rb b/lib/ckb/always_success_wallet.rb index 45f320a..8ae6004 100644 --- a/lib/ckb/always_success_wallet.rb +++ b/lib/ckb/always_success_wallet.rb @@ -100,7 +100,7 @@ def lock_hash def lock_script_json_object { version: 0, - reference: api.always_success_cell_hash, + binary_hash: api.always_success_cell_hash, args: [] } end diff --git a/lib/ckb/udt_wallet.rb b/lib/ckb/udt_wallet.rb index 73c89af..a8dab2c 100644 --- a/lib/ckb/udt_wallet.rb +++ b/lib/ckb/udt_wallet.rb @@ -27,7 +27,7 @@ def initialize(api, name, pubkey, account_wallet) def lock_json_object(pubkey) { version: 0, - reference: api.mruby_cell_hash, + binary_hash: api.mruby_cell_hash, args: [ account_wallet ? UNLOCK_SINGLE_CELL_SCRIPT : UNLOCK_SCRIPT, name, @@ -39,7 +39,7 @@ def lock_json_object(pubkey) def type_json_object { version: 0, - reference: api.mruby_cell_hash, + binary_hash: api.mruby_cell_hash, args: [ CONTRACT_SCRIPT, name, @@ -108,7 +108,7 @@ def fetch_cell def genesis_lock_json_object { version: 0, - reference: api.mruby_cell_hash, + binary_hash: api.mruby_cell_hash, args: [ Ckb::FIXED_AMOUNT_GENESIS_UNLOCK_SCRIPT, input_hash, @@ -126,7 +126,7 @@ def genesis_type_json_object def lock_json_object(pubkey) { version: 0, - reference: api.mruby_cell_hash, + binary_hash: api.mruby_cell_hash, args: [ UNLOCK_SINGLE_CELL_SCRIPT, input_hash, @@ -138,7 +138,7 @@ def lock_json_object(pubkey) def type_json_object { version: 0, - reference: api.mruby_cell_hash, + binary_hash: api.mruby_cell_hash, args: [ Ckb::FIXED_AMOUNT_CONTRACT_SCRIPT, input_hash, diff --git a/lib/ckb/utils.rb b/lib/ckb/utils.rb index 6ad0200..d6990d9 100644 --- a/lib/ckb/utils.rb +++ b/lib/ckb/utils.rb @@ -27,8 +27,8 @@ def self.extract_pubkey_bin(privkey_bin) def self.json_script_to_hash(script) s = Ckb::Blake2b.new - if script[:reference] - s << hex_to_bin(script[:reference]) + if script[:binary_hash] + s << hex_to_bin(script[:binary_hash]) end (script[:args] || []).each do |arg| s << arg @@ -112,8 +112,8 @@ def self.sign_sighash_all_inputs(inputs, outputs, privkey) def self.calculate_script_capacity(script) capacity = 1 + (script[:args] || []).map { |arg| arg.bytesize }.reduce(0, &:+) - if script[:reference] - capacity += Ckb::Utils.hex_to_bin(script[:reference]).bytesize + if script[:binary_hash] + capacity += Ckb::Utils.hex_to_bin(script[:binary_hash]).bytesize end capacity end diff --git a/lib/ckb/wallet.rb b/lib/ckb/wallet.rb index 6ff4274..ebd0d00 100644 --- a/lib/ckb/wallet.rb +++ b/lib/ckb/wallet.rb @@ -388,7 +388,7 @@ def pubkey_hash_bin def verify_script_json_object { version: 0, - reference: api.mruby_cell_hash, + binary_hash: api.mruby_cell_hash, args: [ VERIFY_SCRIPT, # We could of course just hash raw bytes, but since right now CKB From eb7c3b031f15b454db8305fe67f242160d246f05 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Wed, 27 Mar 2019 08:15:40 +0000 Subject: [PATCH 3/4] feat: Remove embeds --- lib/ckb/always_success_wallet.rb | 6 ++---- lib/ckb/udt_wallet.rb | 6 ++---- lib/ckb/wallet.rb | 16 +++++----------- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/lib/ckb/always_success_wallet.rb b/lib/ckb/always_success_wallet.rb index 8ae6004..850c7bc 100644 --- a/lib/ckb/always_success_wallet.rb +++ b/lib/ckb/always_success_wallet.rb @@ -32,8 +32,7 @@ def send_capacity(target_lock, capacity) version: 0, deps: [api.always_success_out_point], inputs: i.inputs, - outputs: outputs, - embeds: [] + outputs: outputs } api.send_transaction(tx) end @@ -64,8 +63,7 @@ def install_mruby_cell!(mruby_cell_filename) version: 0, deps: [api.always_success_out_point], inputs: i.inputs, - outputs: outputs, - embeds: [] + outputs: outputs } hash = api.send_transaction(tx) { diff --git a/lib/ckb/udt_wallet.rb b/lib/ckb/udt_wallet.rb index a8dab2c..74c2d23 100644 --- a/lib/ckb/udt_wallet.rb +++ b/lib/ckb/udt_wallet.rb @@ -283,8 +283,7 @@ def send_amount(amount, partial_tx) version: 0, deps: [api.mruby_out_point], inputs: inputs + self_inputs, - outputs: outputs, - embeds: [] + outputs: outputs } api.send_transaction(tx) end @@ -441,8 +440,7 @@ def send_tokens(amount, target_wallet) version: 0, deps: [api.mruby_out_point], inputs: signed_inputs + [target_input], - outputs: outputs, - embeds: [] + outputs: outputs } api.send_transaction(tx) end diff --git a/lib/ckb/wallet.rb b/lib/ckb/wallet.rb index ebd0d00..b261d39 100644 --- a/lib/ckb/wallet.rb +++ b/lib/ckb/wallet.rb @@ -67,8 +67,7 @@ def generate_tx(target_lock, capacity) version: 0, deps: [api.mruby_out_point], inputs: Ckb::Utils.sign_sighash_all_inputs(i.inputs, outputs, privkey), - outputs: outputs, - embeds: [] + outputs: outputs } end @@ -138,8 +137,7 @@ def create_udt_account_wallet_cell(capacity, token_info) version: 0, deps: [api.mruby_out_point], inputs: Ckb::Utils.sign_sighash_all_inputs(i.inputs, outputs, privkey), - outputs: outputs, - embeds: [] + outputs: outputs } hash = api.send_transaction(tx) # This is in fact an OutPoint here @@ -212,8 +210,7 @@ def create_fixed_amount_token(capacity, tokens, rate, lock: nil) version: 0, deps: [api.mruby_out_point], inputs: Ckb::Utils.sign_sighash_all_inputs(i.inputs, outputs, privkey), - outputs: outputs, - embeds: [] + outputs: outputs } hash = api.send_transaction(tx) OpenStruct.new(tx_hash: hash, token_info: info) @@ -283,8 +280,7 @@ def purchase_fixed_amount_token(tokens, token_info) version: 0, deps: [api.mruby_out_point], inputs: signed_inputs + additional_inputs, - outputs: outputs, - embeds: [] + outputs: outputs } api.send_transaction(tx) end @@ -326,8 +322,7 @@ def create_udt_token(capacity, token_name, tokens, account_wallet: false) version: 0, deps: [api.mruby_out_point], inputs: Ckb::Utils.sign_sighash_all_inputs(i.inputs, outputs, privkey), - outputs: outputs, - embeds: [] + outputs: outputs } hash = api.send_transaction(tx) OpenStruct.new(tx_hash: hash, token_info: token_info) @@ -390,7 +385,6 @@ def verify_script_json_object version: 0, binary_hash: api.mruby_cell_hash, args: [ - VERIFY_SCRIPT, # We could of course just hash raw bytes, but since right now CKB # CLI already uses this scheme, we stick to the same way for compatibility Ckb::Utils.bin_to_hex(pubkey_hash_bin) From c077aa59469f08d5f8044eaba8b63d459d13d4a2 Mon Sep 17 00:00:00 2001 From: Xuejie Xiao Date: Fri, 29 Mar 2019 08:22:59 +0000 Subject: [PATCH 4/4] fix: Fix tests --- lib/ckb/wallet.rb | 2 +- scripts | 2 +- test/ckb/utils_test.rb | 39 ++++++++++++++++----------------------- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/lib/ckb/wallet.rb b/lib/ckb/wallet.rb index b261d39..5a2ce29 100644 --- a/lib/ckb/wallet.rb +++ b/lib/ckb/wallet.rb @@ -9,7 +9,7 @@ require "securerandom" module Ckb - VERIFY_SCRIPT = File.read(File.expand_path("../../../scripts/bitcoin_unlock.rb", __FILE__)) + VERIFY_SCRIPT = File.read(File.expand_path("../../../scripts/secp256k1_blake2b_lock.rb", __FILE__)) class Wallet attr_reader :api diff --git a/scripts b/scripts index 841e05b..ef430db 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 841e05ba9466e38fc81db562f56226d90aeb29f2 +Subproject commit ef430db951d00190f543704954a1328e5c1f5fa9 diff --git a/test/ckb/utils_test.rb b/test/ckb/utils_test.rb index 4245e24..2ac9fbc 100644 --- a/test/ckb/utils_test.rb +++ b/test/ckb/utils_test.rb @@ -23,19 +23,16 @@ def test_calculate_cell_min_capacity output = { capacity: 5000000, data: "", - lock: "0da2fe99fe549e082d4ed483c2e968a89ea8d11aabf5d79e5cbf06522de6e674", - type: { + lock: { args: [], - binary: "0100000000000000", - reference: nil, - signed_args: [], + binary_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: 0 } } - min_capacity = 57 + min_capacity = 41 - assert Ckb::Utils.calculate_cell_min_capacity(output), min_capacity + assert_equal Ckb::Utils.calculate_cell_min_capacity(output), min_capacity end def test_normalize_tx_for_json @@ -48,20 +45,18 @@ def test_normalize_tx_for_json hash: "0x0000000000000000000000000000000000000000000000000000000000000000", index: 4294967295 }, - unlock: { - args: [], - binary: "0x0100000000000000", - reference: nil, - signed_args: [], - version: 0 - } + args: [] } ], outputs: [ { capacity: 5000000, data: "0x", - lock: "0x0da2fe99fe549e082d4ed483c2e968a89ea8d11aabf5d79e5cbf06522de6e674", + lock: { + args: ["0x616263"], + binary_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + version: 0 + }, type: nil } ] @@ -76,20 +71,18 @@ def test_normalize_tx_for_json hash: "0x0000000000000000000000000000000000000000000000000000000000000000", index: 4294967295 }, - unlock: { - args: [], - binary: ["0100000000000000"].pack("H*"), - reference: nil, - signed_args: [], - version: 0 - } + args: [] } ], outputs: [ { capacity: 5000000, data: "", - lock: "0x0da2fe99fe549e082d4ed483c2e968a89ea8d11aabf5d79e5cbf06522de6e674", + lock: { + args: ["abc"], + binary_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + version: 0 + }, type: nil } ]