Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ᚬmaster] Rc/v0.21.0 #175

Merged
merged 46 commits into from
Sep 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
96b5504
Merge pull request #170 from nervosnetwork/master
ashchan Sep 7, 2019
8a8a7f9
test: cell data
shaojunda Sep 12, 2019
4e7d661
feat: add cell data
shaojunda Sep 12, 2019
0ef1ed8
test: cell info
shaojunda Sep 12, 2019
8b47dcb
feat: add cell info
shaojunda Sep 12, 2019
40e85d3
feat: add with_data to get_live_cell
shaojunda Sep 12, 2019
2b5a799
chore: adjust tests
shaojunda Sep 12, 2019
af3f10f
feat: add chain_root to block header
shaojunda Sep 16, 2019
57a04f4
chore: remove duplicate param
shaojunda Sep 16, 2019
10e550b
chore: rename param proposals_root to proposals_hash
shaojunda Sep 16, 2019
676cf7e
test: block header
shaojunda Sep 16, 2019
eaf8a0b
feat: add with_data to get_live_cell (#171)
shaojunda Sep 16, 2019
8fa1014
Merge pull request #172 from shaojunda/shaojunda-add-chain-root-to-he…
classicalliu Sep 16, 2019
148fca6
chore: add chain_root accessor
shaojunda Sep 16, 2019
8bfa661
Merge pull request #173 from shaojunda/shaojunda-add-chain-root-accessor
classicalliu Sep 16, 2019
a1f0495
feat: change all number to integer and convert to hex string in RPC i…
classicalliu Sep 16, 2019
a245ebd
Merge pull request #174 from nervosnetwork/hex-number
ashchan Sep 16, 2019
0a0ae21
chore: use integer since
shaojunda Sep 16, 2019
b14b0fb
chore: use correct param name
shaojunda Sep 16, 2019
00c8d5d
Merge pull request #176 from shaojunda/shaojunda-update-since-default…
classicalliu Sep 16, 2019
41b3e46
test: new type addresses
shaojunda Sep 17, 2019
d2b7a98
feat: implement new type addresses
shaojunda Sep 17, 2019
eda8fd5
feat: remove chain_root from header
classicalliu Sep 16, 2019
4eaaf91
chore: rename address variables
shaojunda Sep 18, 2019
55abb63
feat: add with_hash to transaction to_h
shaojunda Sep 18, 2019
2752fe8
feat: remove chain_root from header (#179)
shaojunda Sep 18, 2019
9e14366
feat: add to_raw_transaction_h method
shaojunda Sep 18, 2019
9af182c
feat: support new format address (#177)
shaojunda Sep 18, 2019
51f7c00
Merge pull request #178 from shaojunda/shaojunda-use-strict-on-rpc
ashchan Sep 18, 2019
66dc62a
feat: add errors on Address
shaojunda Sep 19, 2019
8ae8a32
chore: adjust tests
shaojunda Sep 19, 2019
871433c
refactor: change arg verification rule
shaojunda Sep 19, 2019
221ca15
test: empty arg
shaojunda Sep 19, 2019
fae5650
refactor: rename tests
shaojunda Sep 19, 2019
55a6dcc
refactor: merge two type address parser to one
shaojunda Sep 19, 2019
1b040b9
test: parse with invalid format type and code hash index
shaojunda Sep 19, 2019
1478144
feat: add error on address (#180)
shaojunda Sep 19, 2019
10fed4d
refactor: address parse (#181)
shaojunda Sep 19, 2019
c3c9af7
fix: return hex string format type
shaojunda Sep 19, 2019
f836c28
chore: adjust tests
shaojunda Sep 19, 2019
219f749
Merge pull request #182 from shaojunda/shaojunda-return-hex-string-on…
classicalliu Sep 19, 2019
4a7ea7e
feat: change to class method
shaojunda Sep 19, 2019
e9c5e90
chore: adjust tests
shaojunda Sep 19, 2019
ea95b33
feat: use class method (#183)
shaojunda Sep 19, 2019
46a372b
chore: bump version to 0.21.0
classicalliu Sep 20, 2019
87ef418
docs: update CHANGELOG for v0.21.0
classicalliu Sep 20, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

# [v0.21.0](https://github.com/nervosnetwork/ckb-sdk-ruby/compare/v0.20.0...v0.21.0) (2019-09-21)


### Bug Fixes

* return hex string format type ([c3c9af7](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/c3c9af7))


### Features

* add cell data ([4e7d661](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/4e7d661))
* add cell info ([8b47dcb](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/8b47dcb))
* add chain_root to block header ([af3f10f](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/af3f10f))
* add errors on Address ([66dc62a](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/66dc62a))
* add to_raw_transaction_h method ([9e14366](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/9e14366))
* add with_data to get_live_cell ([40e85d3](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/40e85d3))
* add with_hash to transaction to_h ([55abb63](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/55abb63))
* change all number to integer and convert to hex string in RPC interface ([a1f0495](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/a1f0495))
* change to class method ([4a7ea7e](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/4a7ea7e))
* implement new type addresses ([d2b7a98](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/d2b7a98))


### BREAKING CHANGES

* All number type changed to integer and will convert to hex string in RPC interface


# [v0.20.0](https://github.com/nervosnetwork/ckb-sdk-ruby/compare/v0.19.0...v0.20.0) (2019-09-07)


Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
ckb-sdk-ruby (0.20.0)
ckb-sdk-ruby (0.21.0)
bitcoin-secp256k1 (~> 0.5.2)
net-http-persistent (~> 3.0.0)
rbnacl (~> 6.0, >= 6.0.1)
Expand Down
2 changes: 1 addition & 1 deletion lib/bech32.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def decode(bech)
bech = bech.downcase
# check data length
pos = bech.rindex(SEPARATOR)
return nil if pos.nil? || pos < 1 || pos + 7 > bech.length || bech.length > 90
return nil if pos.nil? || pos < 1 || pos + 7 > bech.length
# check valid charset
bech[pos+1..-1].each_char{|c|return nil unless CHARSET.include?(c)}
# split hrp and data
Expand Down
111 changes: 102 additions & 9 deletions lib/ckb/address.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class Address

DEFAULT_MODE = MODE::TESTNET

TYPE = "01"
CODE_HASH_INDEX = "00"
TYPES = %w(01 02 04)
CODE_HASH_INDEXES = %w(00 01)

def initialize(blake160, mode: DEFAULT_MODE)
@mode = mode
Expand All @@ -21,39 +21,126 @@ def initialize(blake160, mode: DEFAULT_MODE)

# Generates address assuming default lock script is used
# payload = type(01) | code hash index(00) | pubkey blake160
# see https://github.com/nervosnetwork/ckb/wiki/Common-Address-Format for more info.
# see https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0021-ckb-address-format/0021-ckb-address-format.md for more info.
def generate
blake160_bin = [blake160[2..-1]].pack("H*")
type = [TYPE].pack("H*")
code_hash_index = [CODE_HASH_INDEX].pack("H*")
type = [TYPES[0]].pack("H*")
code_hash_index = [CODE_HASH_INDEXES[0]].pack("H*")
payload = type + code_hash_index + blake160_bin
ConvertAddress.encode(@prefix, payload)
end

# Generates short payload format address
# payload = type(01) | code hash index(01) | pubkey hash160
# see https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0021-ckb-address-format/0021-ckb-address-format.md for more info.
# @param [String] hash160
# @return [String]
def self.generate_short_payload_hash160_address(hash160, mode: DEFAULT_MODE)
prefix = prefix(mode: mode)
hash160_bin = [hash160[2..-1]].pack("H*")
type = [TYPES[0]].pack("H*")
code_hash_index = [CODE_HASH_INDEXES[1]].pack("H*")
payload = type + code_hash_index + hash160_bin
ConvertAddress.encode(prefix, payload)
end

# Generates full payload format address
# payload = 0x02/0x04 | code_hash | len(arg[0]) | arg[0] | ...
# see https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0021-ckb-address-format/0021-ckb-address-format.md for more info.
# @param [String | Integer] format_type
# @param [String] code_hash
# @param [String[]] args
# @return [String]
def self.generate_full_payload_address(format_type, code_hash, args, mode: DEFAULT_MODE)
prefix = prefix(mode: mode)
format_type = Utils.to_hex(format_type)[2..-1].rjust(2, '0')
raise InvalidFormatTypeError.new("Invalid format type") unless TYPES[1..-1].include?(format_type)
raise InvalidArgsTypeError.new("Args should be an array") unless args.is_a?(Array)

payload = [format_type].pack("H*") + CKB::Utils.hex_to_bin(code_hash)
args.each do |arg|
arg_bytes = CKB::Utils.hex_to_bin(arg)
arg_len = arg_bytes.bytesize
if arg_len > 256
raise InvalidArgSizeError.new("The maximum size of arg is 256")
else
payload += [arg_len].pack("C") + arg_bytes
end
end

CKB::ConvertAddress.encode(prefix, payload)
end

alias to_s generate

# Parse address into lock assuming default lock script is used
def parse(address)
self.class.parse(address, mode: @mode)
end

def self.parse(address, mode: DEFAULT_MODE)
def self.parse_short_payload_address(address, mode: DEFAULT_MODE)
decoded_prefix, data = ConvertAddress.decode(address)
format_type = data[0].unpack("H*").first
code_hash_index = data[1].unpack("H*").first

raise "Invalid prefix" if decoded_prefix != prefix(mode: mode)

raise "Invalid type/code hash index" if data.slice(0..1) != [TYPE + CODE_HASH_INDEX].pack("H*")
raise InvalidPrefixError.new("Invalid prefix") if decoded_prefix != prefix(mode: mode)
raise InvalidFormatTypeError.new("Invalid format type") if format_type != TYPES[0]
raise InvalidCodeHashIndexError.new("Invalid code hash index") unless CODE_HASH_INDEXES.include?(code_hash_index)

CKB::Utils.bin_to_hex(data.slice(2..-1))
end

def self.parse_full_payload_address(address, mode: DEFAULT_MODE)
decoded_prefix, data = ConvertAddress.decode(address)
format_type = data[0].unpack("H*").first

raise InvalidPrefixError.new("Invalid prefix") if decoded_prefix != prefix(mode: mode)
raise InvalidFormatTypeError.new("Invalid format type") unless TYPES[1..-1].include?(format_type)

offset = 1
code_hash_size = 32
code_hash = "0x#{data.slice(offset..code_hash_size).unpack("H*").first}"
offset += 32
data_size = data.bytesize
args = []
while offset < data_size
arg_len = data[offset].unpack("C").first.to_i
offset += 1
arg = data[offset...offset + arg_len]
args << arg
offset += arg_len
end

["0x#{format_type}", code_hash, args.map { |item| CKB::Utils.bin_to_hex(item) }]
end

def self.parse(address, mode: DEFAULT_MODE)
_decoded_prefix, data = ConvertAddress.decode(address)
format_type = data[0].unpack("H*").first
case format_type
when "01"
parse_short_payload_address(address, mode: mode)
when "02", "04"
parse_full_payload_address(address, mode: mode)
else
raise InvalidFormatTypeError.new("Invalid format type")
end
end

def self.blake160(pubkey)
pubkey = pubkey[2..-1] if pubkey.start_with?("0x")
pubkey_bin = [pubkey].pack("H*")
hash_bin = CKB::Blake2b.digest(pubkey_bin)
Utils.bin_to_hex(hash_bin[0...20])
end

def self.hash160(pubkey)
pubkey = pubkey[2..-1] if pubkey.start_with?("0x")
pub_key_sha256 = Digest::SHA256.hexdigest(pubkey)

"0x#{Digest::RMD160.hexdigest(pub_key_sha256)}"
end

def self.from_pubkey(pubkey, mode: DEFAULT_MODE)
new(blake160(pubkey), mode: mode)
end
Expand All @@ -66,5 +153,11 @@ def self.prefix(mode: DEFAULT_MODE)
PREFIX_MAINNET
end
end

class InvalidFormatTypeError < StandardError; end
class InvalidArgsTypeError < StandardError; end
class InvalidArgSizeError < StandardError; end
class InvalidPrefixError < StandardError; end
class InvalidCodeHashIndexError < StandardError; end
end
end
31 changes: 16 additions & 15 deletions lib/ckb/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def initialize(host: CKB::RPC::DEFAULT_URL, mode: MODE::TESTNET)
secp_group_cell_transaction = genesis_block.transactions[1]
secp_group_out_point = Types::OutPoint.new(
tx_hash: secp_group_cell_transaction.hash,
index: "0"
index: 0
)

secp_cell_type_hash = system_cell_transaction.outputs[1].type.compute_hash
Expand All @@ -43,7 +43,7 @@ def initialize(host: CKB::RPC::DEFAULT_URL, mode: MODE::TESTNET)

dao_out_point = Types::OutPoint.new(
tx_hash: system_cell_transaction.hash,
index: "2"
index: 2
)
dao_cell_data = CKB::Utils.hex_to_bin(system_cell_transaction.outputs_data[2])
dao_code_hash = CKB::Blake2b.hexdigest(dao_cell_data)
Expand All @@ -65,16 +65,16 @@ def set_dao_dep(out_point, code_hash)
end

def genesis_block
@genesis_block ||= get_block_by_number("0")
@genesis_block ||= get_block_by_number(0)
end

def genesis_block_hash
@genesis_block_hash ||= get_block_hash("0")
@genesis_block_hash ||= get_block_hash(0)
end

# @return [String | Integer]
def get_block_hash(block_number)
rpc.get_block_hash(block_number.to_s)
rpc.get_block_hash(block_number)
end

# @param block_hash [String] 0x...
Expand All @@ -89,7 +89,7 @@ def get_block(block_hash)
#
# @return [CKB::Types::Block]
def get_block_by_number(block_number)
block_h = rpc.get_block_by_number(block_number.to_s)
block_h = rpc.get_block_by_number(block_number)
Types::Block.from_h(block_h)
end

Expand All @@ -101,7 +101,7 @@ def get_tip_header

# @return [String]
def get_tip_block_number
rpc.get_tip_block_number
Utils.to_int(rpc.get_tip_block_number)
end

# @param hash [String] 0x...
Expand All @@ -110,7 +110,7 @@ def get_tip_block_number
#
# @return [CKB::Types::Output[]]
def get_cells_by_lock_hash(hash, from, to)
outputs = rpc.get_cells_by_lock_hash(hash, from.to_s, to.to_s)
outputs = rpc.get_cells_by_lock_hash(hash, from, to)
outputs.map { |output| Types::Output.from_h(output) }
end

Expand All @@ -123,22 +123,23 @@ def get_transaction(tx_hash)
end

# @param out_point [CKB::Types::OutPoint]
# @param with_data [Boolean]
#
# @return [CKB::Types::CellWithStatus]
def get_live_cell(out_point)
cell_h = rpc.get_live_cell(out_point.to_h)
def get_live_cell(out_point, with_data = false)
cell_h = rpc.get_live_cell(out_point.to_h, with_data)
Types::CellWithStatus.from_h(cell_h)
end

# @param transaction [CKB::Types::Transaction]
#
# @return [String] tx_hash
def send_transaction(transaction)
rpc.send_transaction(transaction.to_h)
rpc.send_transaction(transaction.to_raw_transaction_h)
end

def compute_transaction_hash(transaction)
rpc.compute_transaction_hash(transaction.to_h)
rpc.compute_transaction_hash(transaction.to_raw_transaction_h)
end

def compute_script_hash(script)
Expand Down Expand Up @@ -194,7 +195,7 @@ def get_peers_state
#
# @return [CKB::Types::DryRunResult]
def dry_run_transaction(transaction)
result = rpc.dry_run_transaction(transaction.to_h)
result = rpc.dry_run_transaction(transaction.to_raw_transaction_h)
Types::DryRunResult.from_h(result)
end

Expand Down Expand Up @@ -245,7 +246,7 @@ def get_transactions_by_lock_hash(lock_hash, page, per, reverse_order: false)
# @param index_from [String]
#
# @return [Types::LockHashIndexState]
def index_lock_hash(lock_hash, index_from: "0")
def index_lock_hash(lock_hash, index_from: 0)
state = rpc.index_lock_hash(lock_hash, index_from: index_from)
Types::LockHashIndexState.from_h(state)
end
Expand All @@ -262,7 +263,7 @@ def get_header(block_hash)
#
# @return [CKB::Types::BlockHeader]
def get_header_by_number(block_number)
block_header_h = rpc.get_header_by_number(block_number.to_s)
block_header_h = rpc.get_header_by_number(block_number)
Types::BlockHeader.from_h(block_header_h)
end

Expand Down
Loading