Skip to content

Instantly share code, notes, and snippets.

@fuyuton
Last active October 5, 2020 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fuyuton/87b5f4d2d9cd9e8801b3cc265c1ed925 to your computer and use it in GitHub Desktop.
Save fuyuton/87b5f4d2d9cd9e8801b3cc265c1ed925 to your computer and use it in GitHub Desktop.
bitcoin-rubyでmonapartyのトークンを送れるようにするコード
# frozen_string_literal: true
source "https://rubygems.org"
gem 'bitcoin-ruby', git: 'https://github.com/fuyuton/bitcoin-ruby', branch: 'master', require: 'bitcoin'
require 'json'
require "uri"
require "net/http"
require 'bitcoin'
class Http_Client
def initialize(url)
@url = url
@https = Net::HTTP.new(@url.host, @url.port);
@https.use_ssl = true
@request = Net::HTTP::Post.new(@url)
@request["Content-Type"] = "application/json"
end
def post(json)
@request.body = json
response = @https.request(@request)
JSON.parse(response.read_body)
end
end
class Monaparty
def initialize(network, url, is_testnet)
@api = Http_Client.new(url)
#ネットワークの指定
#多分これであってるだろう(元にしたコードにあったコメント)
Bitcoin.network = is_testnet ? "#{network}_testnet".to_sym : network.to_sym
end
def valid_address?(address)
Bitcoin.valid_address?(address)
end
#MONAの残高を見る
def get_balance_basecoin(address)
json = create_json("get_chain_address_info", {"addresses":["#{address}"],"with_uxtos":"True","with_last_txn_hashes":"4"})
@api.post(json)
balance = ''
res['result'].each {|elem|
info = elem['info']
balance = info['balance'] if info['addrStr'] == address
}
balance
end
#アセット(トークン)の残高を見る
def get_balance_token(address)
json = create_json("get_normalized_balances", {"addresses":["#{address}"]})
@api.post(json)
balance = ''
if !res['result'].empty?
res['result'].each {|elem|
balance = elem['normalized_quantity'] if elem['address'] == address
}
end
balance
end
def get_raw_transaction(tx_hash, verbose=false, skip_missing=false)
json = create_proxy_json("getrawtransaction", {"tx_hash": "#{tx_hash}", "verbose": verbose, "skip_missing": skip_missing })
res = @api.post(json)
verbose ? res['result']['hex'] : res['result']
end
def create_unsigned_tx(src, dest, asset, qty, fee, is_enhanced_send=true, mona_qty=54600)
json = create_proxy_json(
"create_send",
{
"source": src,
"destination": dest,
"asset": asset,
"quantity": qty*100000000,
"fee_per_kb": fee * 1024,
"use_enhanced_send": is_enhanced_send,
"allow_unconfirmed_inputs": false,
"disable_utxo_locks": true,
"encoding": "auto",
"extended_tx_info": true,
"regular_dust_size": mona_qty,
}
)
res = @api.post(json)
if res.has_key?('result') && res['result'].has_key?('tx_hex')
unsigned_tx = res['result']['tx_hex']
puts "\nunsigned_tx: #{unsigned_tx}"
else
puts "#{__method__} Error:\n"
puts "#{res}\n"
exit
end
unsigned_tx
end
def sign(unsigned_tx, secret)
#鍵の準備
key = Bitcoin::Key.from_base58 secret
pubkey = [key.pub].pack('H*')
#トランザクションを作る
#成功バージョン(ただしdust monaも送られる)
tx = Bitcoin::Protocol::Tx.new([unsigned_tx].pack("H*"))
prev_hash = tx.in[0].prev_out.reverse_hth
prev_tx_hex = [get_raw_transaction(prev_hash)].pack('H*')
prev_tx = Bitcoin::Protocol::Tx.new prev_tx_hex
subscript = tx.signature_hash_for_input 0, prev_tx
#署名する
signed_tx = Bitcoin.sign_data(Bitcoin.open_key(key.priv), subscript)
tx.in[0].script_sig = Bitcoin::Script.to_signature_pubkey_script signed_tx, pubkey
signed_tx_hex = tx.to_payload.unpack('H*')[0]
end
def broadcast(signed_tx_hex)
json = create_json("broadcast_tx", {signed_tx_hex: signed_tx_hex})
res = @api.post(json)
if res.has_key?('result')
txid = res['result']
else
puts "#{__method__} Error:\n"
puts "#{res}\n"
exit
end
txid
end
private
def create_json(method, params)
%Q{{
"jsonrpc": "2.0",
"id": 0,
"method": "#{method}",
"params": #{params.to_json}
}}
end
def create_proxy_json(method, params)
%Q{{
"jsonrpc": "2.0",
"id": 0,
"method":
"proxy_to_counterpartyd",
"params":
{
"method": "#{method}",
"params": #{params.to_json}
}
}}
end
end
if __FILE__ == $0
network = "monacoin"
is_testnet = true
if !is_testnet
#url = URI("https://wallet.monaparty.me/_api")
url = URI("https://monapa.electrum-mona.org/_api")
src_address = ""
dest_address = ""
secret = ""
else
#テストネットにつなぐときは、endpointを /_t_api にする
url = URI("https://testnet-monapa.electrum-mona.org/_t_api")
#url = URI("https://wallet-testnet.monaparty.me/_t_api")
src_address = ""
dest_address = ""
secret = ""
end
mp = Monaparty.new(network, url, is_testnet)
avs = mp.valid_address?(src_address)
avd = mp.valid_address?(dest_address)
if !avs || !avd
puts "source_address valid? #{avs}" if !avs
puts "destination_address valid? #{avd}" if !avd
exit
end
asset = "XMP"
token_qty = 1
fee_satoshi = 110
#未署名トランザクションを作る
unsigned_tx = mp.create_unsigned_tx(src_address, dest_address, asset, token_qty, fee_satoshi)
#monaを送るときの書き方
#qty_watanabe = 100000000
#unsigned_tx = mp.create_unsigned_tx(src_address, dest_address, asset, token_qty, fee_satoshi, false, qty_watanabe)
#未署名トランザクションに署名する
signed_tx_hex = mp.sign(unsigned_tx, secret)
puts "signed_tx_hex: #{signed_tx_hex}"
#署名されたトランザクションを送信する
txid = mp.broadcast(signed_tx_hex)
puts "txid: #{txid}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment