freddiecoleman / chia-client

TypeScript client for Chia RPC interfaces.
https://www.chiaexplorer.com/
MIT License
89 stars 43 forks source link

how to generate coin_info #17

Open xianggy opened 3 years ago

xianggy commented 3 years ago

coinID == sha256(parent_ID + puzzlehash + amount) I found it from https://chialisp.com/docs/doc2

I tried it with Nodejs and still not correct. console.log(CryptoJS.SHA256('f7e09a94c5da73019577b288aeedaf4750540ecca091bb5c4bcf45dacb3a0485' + 'ee12091f293040e42999c64d471ec9a65692f1dde0c42a4936d80e25a8d0535c' + 299700000000).toString()) // return e8ad8111fd2761792b9b39a531117ca8edcbc4ba65b2c3d9472c63dd76876731 not matched 6dddefd62523efccacf35e0cac24cc5348dde8f40ae48be1c563a9404e8251fe

So what the type of these params are? Can someone provide any examples? Thank you.

xianggy commented 3 years ago

fixed it.

//let CryptoJS = require("crypto-js"); // not work
let crypto = require('crypto')
let getCoinInfo = function(parent_coin_info, puzzle_hash, amount) {
    let a = Buffer.from(parent_coin_info, 'hex')
    let b = Buffer.from(puzzle_hash, 'hex')
    let c = Buffer.from((amount).toString(16), 'hex')
    let d = Buffer.concat([a, b, c], a.length + b.length + c.length);
    const hash = crypto.createHash('sha256')
    hash.update(d)
    return hash.digest('hex')
}
console.log(getCoinInfo('f7e09a94c5da73019577b288aeedaf4750540ecca091bb5c4bcf45dacb3a0485', 'ee12091f293040e42999c64d471ec9a65692f1dde0c42a4936d80e25a8d0535c', 299700000000))
sibitha-bijesh commented 3 years ago

its not working in my case getCoinInfo('0xccd5bb71183532bff220ba46c268991a0000000000000000000000000003901f', '0x4bc6435b409bcbabe53870dae0f03755f6aabb4594c5915ec983acf12a5d1fba', 1507629710000)

sibitha-bijesh commented 3 years ago

Do I need to change my amount to any other format? Please suggest

xianggy commented 3 years ago

@sibitha-bijesh no 0x.

crcrcr999 commented 3 years ago

Still have problem,watch this: console.log(getCoinInfo('66b5ee60a2cbba93951a534cfa76d31adc98542dcc5bac95e63572fbaf652576', '38b99b01362d6bb46d2cb55b8a04b73bea29a4dc565061be9eb79aead7a064d6', 1100000000)) return correct value ‘35bbe3ad5bed7165e4837124a7df8f9a7363a519f4ade8920af9315fb6326e09’

but this https://www.chiaexplorer.com/blockchain/coin/0x5615ca8684e921b6bf2c0542bd5f878df62bf3c0154856a2793eae5167a17461 or this https://www.chiaexplorer.com/blockchain/coin/0xf48e1a969fe4d4fbb361c9afa89e2f2d3ad30434013873ea601d2895b6cb6e94 return wrong value

crcrcr999 commented 3 years ago

我猜大概是因为后两笔金额过小? 大于0.001的时候是正确的

xianggy commented 3 years ago

嗯,好像跟金额大小无关,这笔也对不上。https://www.chiaexplorer.com/blockchain/coin/0xae60b29897249c86cd5d0a69db141ab20519dc12b371f87f1efef758f7283787

crcrcr999 commented 3 years ago

解决了 let amounthex=amount.toString(16); if(amounthex.length%2==1){ amounthex='0'+amounthex; } let c = Buffer.from(amounthex, 'hex') 如果金额转hex长度为单数 需要在前面补0 ... 灵光一闪想到的居然成了

oncecsc commented 3 years ago

解决了 let amounthex=amount.toString(16); if(amounthex.length%2==1){ amounthex='0'+amounthex; } let c = Buffer.from(amounthex, 'hex') 如果金额转hex长度为单数 需要在前面补0 ... 灵光一闪想到的居然成了

下面这笔也对不上 https://www.chiaexplorer.com/blockchain/coin/0xae60b29897249c86cd5d0a69db141ab20519dc12b371f87f1efef758f7283787

    const { createHash } = require("crypto");

    const parentCoinInfo = 'f2a908698aa5c00ecbd7792bf3ce801317f53ed6544ad8e6e8ba4bd54853b9dd';
    const puzzleHash = 'a73e6bcbdcdf7acafb63d240fc67f53115768a991be645246cac2f3a1ffef53b';
    const amount = 1049500000000

    const getCoinInfo = function (parentCoinInfo, puzzleHash, amount) {
      const a = Buffer.from(parentCoinInfo, 'hex')
      const b = Buffer.from(puzzleHash, 'hex')
      let amountHex = amount.toString(16);
      if (amountHex.length % 2 == 1) {
        amountHex = '0' + amountHex
      }
      const c = Buffer.from(amountHex, 'hex');

      const d = Buffer.concat([a, b, c], a.length + b.length + c.length);
      const hash = createHash('sha256');
      hash.update(d);
      return hash.digest('hex')
    }

    console.log(getCoinInfo(parentCoinInfo, puzzleHash, amount))
oncecsc commented 3 years ago

官方只给出了python计算coin ID方法, 找了一圈没找到其他语言计算coin ID方法。 我在fullNode上加了一个计算coin ID 的rpc方法,将就用一下

在 chia-blockchain/chia/rpc/full_node_rpc_api.py文件中导入 Coin:

from chia.types.blockchain_format.coin import Coin

在FullNodeRpcApi类中添加方法:

    async def get_coin_id(self, request: Dict):
        """
        Returns coin id
        """
        return  {"coin_id": Coin(hexstr_to_bytes(request["parent_coin_info"]), hexstr_to_bytes(request["puzzle_hash"]), int(request["amount"])).name()}

get_routes方法返回值中加一行: "/get_coin_id": self.get_coin_id,

crcrcr999 commented 3 years ago

解决了 let amounthex=amount.toString(16); if(amounthex.length%2==1){ amounthex='0'+amounthex; } let c = Buffer.from(amounthex, 'hex') 如果金额转hex长度为单数 需要在前面补0 ... 灵光一闪想到的居然成了

下面这笔也对不上 https://www.chiaexplorer.com/blockchain/coin/0xae60b29897249c86cd5d0a69db141ab20519dc12b371f87f1efef758f7283787

    const { createHash } = require("crypto");

    const parentCoinInfo = 'f2a908698aa5c00ecbd7792bf3ce801317f53ed6544ad8e6e8ba4bd54853b9dd';
    const puzzleHash = 'a73e6bcbdcdf7acafb63d240fc67f53115768a991be645246cac2f3a1ffef53b';
    const amount = 1049500000000

    const getCoinInfo = function (parentCoinInfo, puzzleHash, amount) {
      const a = Buffer.from(parentCoinInfo, 'hex')
      const b = Buffer.from(puzzleHash, 'hex')
      let amountHex = amount.toString(16);
      if (amountHex.length % 2 == 1) {
        amountHex = '0' + amountHex
      }
      const c = Buffer.from(amountHex, 'hex');

      const d = Buffer.concat([a, b, c], a.length + b.length + c.length);
      const hash = createHash('sha256');
      hash.update(d);
      return hash.digest('hex')
    }

    console.log(getCoinInfo(parentCoinInfo, puzzleHash, amount))

试了一下 这笔计算的金额的hex前面要再加2个0 .. 至于为什么 目前判断是如果amount转换的第一位是字母 需要再补2个0

ygcool commented 3 years ago

求一个php版本的转换coinid. 感激不尽

crcrcr999 commented 3 years ago

求一个php版本的转换coinid. 感激不尽

没学过php 按照步骤上网搜了一下写了一个: https://gist.github.com/crcrcr999/142f4386bef7dc31a8c6ee67249b54bb

<?php 
    function hexToStr($hex){
            $string='';
            for ($i=0; $i < strlen($hex)-1; $i+=2){
            $string .= chr(hexdec($hex[$i].$hex[$i+1]));
            }
            return $string;
    }

    function getCoinId($parent_coin_info,$puzzle_hash,$amount){
            $coinId='';
        $amountHex=dechex($amount);
        while(strlen($amountHex)%2>0){
            $amountHex='0'.$amountHex;
        }
        if(!is_numeric(substr($amountHex,0,1))){
            $amountHex='00'.$amountHex;
        }
        $coinId=hash('sha256', hexToStr($parent_coin_info.$puzzle_hash.$amountHex));
            return $coinId;
    }

    $coinid=getCoinId('ccd5bb71183532bff220ba46c268991a00000000000000000000000000000000','d23da14695a188ae5708dd152263c4db883eb27edeb936178d4d988b8f3ce5fc',18375000000000000000);
    echo 'coinId值:'.$coinid;
?> 

用的菜鸟教程的在线编辑器写的 没有怎么处理格式 将就看吧 思路大概是这么个思路

ygcool commented 3 years ago

求一个php版本的转换coinid. 感激不尽

没学过php 按照步骤上网搜了一下写了一个: https://gist.github.com/crcrcr999/142f4386bef7dc31a8c6ee67249b54bb `

0){ $amountHex='0'.$amountHex; } if(!is_numeric(substr($amountHex,0,1))){ $amountHex='00'.$amountHex; } echo $amountHex; $coinId=hash('sha256', hexToStr($parent_coin_info.$puzzle_hash.$amountHex)); return $coinId; } $coinid=getCoinId('ccd5bb71183532bff220ba46c268991a00000000000000000000000000000000','d23da14695a188ae5708dd152263c4db883eb27edeb936178d4d988b8f3ce5fc',18375000000000000000); echo 'coinId值:'.$coinid; ?> `

非常感谢!

CMEONE commented 3 years ago

For all interested, I've created the chia-utils node module which includes methods that solve this issue: https://www.npmjs.com/package/chia-utils https://github.com/CMEONE/chia-utils

xw332 commented 3 years ago

For all interested, I've created the chia-utils node module which includes methods that solve this issue: https://www.npmjs.com/package/chia-utils https://github.com/CMEONE/chia-utils

const parentCoinInfo = 'f2a908698aa5c00ecbd7792bf3ce801317f53ed6544ad8e6e8ba4bd54853b9dd'; const puzzleHash = 'a73e6bcbdcdf7acafb63d240fc67f53115768a991be645246cac2f3a1ffef53b'; const amount = 1049500000000

I use get_coin_info from chia-utils, get 0x38976d54b506c2a955022601368c943fa081ffce1fcfeaa1bf95bfa10d714f54 but the url is https://www.chiaexplorer.com/blockchain/coin/0xae60b29897249c86cd5d0a69db141ab20519dc12b371f87f1efef758f7283787

1.0495 * 1000000000000 = 1049500000000.0001, if not use BigInt so, Is this a bug

CMEONE commented 3 years ago

@xw332 Please use const amount = 1.0495, get_coin_info uses the XCH decimal amount instead of the mojo amount (if you are getting amount 1049500000000, do 1049500000000/1000000000000

xw332 commented 3 years ago

@xw332 Please use const amount = 1.0495, get_coin_info uses the XCH decimal amount instead of the mojo amount (if you are getting amount 1049500000000, do 1049500000000/1000000000000

but 1049500000000 / 1000000000000 * 1000000000000 = 1049500000000.0001 test case: https://www.chiaexplorer.com/blockchain/coin/0xae60b29897249c86cd5d0a69db141ab20519dc12b371f87f1efef758f7283787 https://www.chiaexplorer.com/blockchain/coin/0x226bee197e358e60c25d907d5ad2db0c4508861a1d66b8438602bb31ac43aa0c

@CMEONE

CMEONE commented 3 years ago

Yes, there seems to be an issue with large numbers, I'll take a look.

wbm0701 commented 3 years ago

求一个java的~

CMEONE commented 3 years ago

@xw332 Bug has been fixed in v1.0.4.

litterGuy commented 3 years ago

碰见一个情况不一致的

amount : 2300000000
parent_coin_info : 0xadc79e3d3295eb6e32c138f0f0c3466344bb7be31c0ffb02861c4189fd9942d5
puzzle_hash : 0xb39e0ae17737489a080d9693759b7af709a0ee56ba885acd2dae9f1f3ca67092

amount的16进制为89173700,转换的第一位不是字母。 生成的coinid是 0xabee1e7951df211c1bdd077506b551b5fbe7d2ca00086e8a208160d6f0f56242 但是浏览器查看实际为https://www.chiaexplorer.com/blockchain/coin/0xa48ae3986b5a27e7d46608ea91dea2b097127a4a21a04507c28aee33222a776f

这个尝试了下,是头部添加两个0生成的。

请问一下,这种需要根据什么情况判断?

litterGuy commented 3 years ago

碰见一个情况不一致的

amount : 2300000000
parent_coin_info : 0xadc79e3d3295eb6e32c138f0f0c3466344bb7be31c0ffb02861c4189fd9942d5
puzzle_hash : 0xb39e0ae17737489a080d9693759b7af709a0ee56ba885acd2dae9f1f3ca67092

amount的16进制为89173700,转换的第一位不是字母。 生成的coinid是 0xabee1e7951df211c1bdd077506b551b5fbe7d2ca00086e8a208160d6f0f56242 但是浏览器查看实际为https://www.chiaexplorer.com/blockchain/coin/0xa48ae3986b5a27e7d46608ea91dea2b097127a4a21a04507c28aee33222a776f

这个尝试了下,是头部添加两个0生成的。

请问一下,这种需要根据什么情况判断?

参照大佬的https://github.com/CMEONE/chia-utils 写了go的实现 https://github.com/litterGuy/chia_utils

qwIvan commented 3 years ago

因爲uint需要使用多一位來表示正負數數,所以當amount佔用的位數剛好爲8的倍數時,需要補多一位,因此在某些情況下補一個0並不夠,要補兩個0。 例如當amount爲33152時,二進制是1000000110000000,剛好16位,是8的倍數,同時33152的十六進制又是0x8180,是偶數,所以需要補多兩個0,變爲0x008180

qwIvan commented 3 years ago

解决了 let amounthex=amount.toString(16); if(amounthex.length%2==1){ amounthex='0'+amounthex; } let c = Buffer.from(amounthex, 'hex') 如果金额转hex长度为单数 需要在前面补0 ... 灵光一闪想到的居然成了

下面这笔也对不上 https://www.chiaexplorer.com/blockchain/coin/0xae60b29897249c86cd5d0a69db141ab20519dc12b371f87f1efef758f7283787

    const { createHash } = require("crypto");

    const parentCoinInfo = 'f2a908698aa5c00ecbd7792bf3ce801317f53ed6544ad8e6e8ba4bd54853b9dd';
    const puzzleHash = 'a73e6bcbdcdf7acafb63d240fc67f53115768a991be645246cac2f3a1ffef53b';
    const amount = 1049500000000

    const getCoinInfo = function (parentCoinInfo, puzzleHash, amount) {
      const a = Buffer.from(parentCoinInfo, 'hex')
      const b = Buffer.from(puzzleHash, 'hex')
      let amountHex = amount.toString(16);
      if (amountHex.length % 2 == 1) {
        amountHex = '0' + amountHex
      }
      const c = Buffer.from(amountHex, 'hex');

      const d = Buffer.concat([a, b, c], a.length + b.length + c.length);
      const hash = createHash('sha256');
      hash.update(d);
      return hash.digest('hex')
    }

    console.log(getCoinInfo(parentCoinInfo, puzzleHash, amount))

试了一下 这笔计算的金额的hex前面要再加2个0 .. 至于为什么 目前判断是如果amount转换的第一位是字母 需要再补2个0

所以以下是我的補0方法。

amountHex = '0'.repeat((Math.ceil(Math.log2(amount))+8>>3<<1)-amountHex.length) + amountHex
CMEONE commented 3 years ago

@qwIvan What version are you running (use npm list to see the version)? I thought v1.0.4 of chia-utils fixed this bug in node.js and v1.0.5 fixed it in the browser. Please check your version and reinstall if necessary and try to see if the newer version solves the issue. If the issue is still there, I can add your code into the library.

crcrcr999 commented 3 years ago

解决了 let amounthex=amount.toString(16); if(amounthex.length%2==1){ amounthex='0'+amounthex; } let c = Buffer.from(amounthex, 'hex') 如果金额转hex长度为单数 需要在前面补0 ... 灵光一闪想到的居然成了

下面这笔也对不上 https://www.chiaexplorer.com/blockchain/coin/0xae60b29897249c86cd5d0a69db141ab20519dc12b371f87f1efef758f7283787

    const { createHash } = require("crypto");

    const parentCoinInfo = 'f2a908698aa5c00ecbd7792bf3ce801317f53ed6544ad8e6e8ba4bd54853b9dd';
    const puzzleHash = 'a73e6bcbdcdf7acafb63d240fc67f53115768a991be645246cac2f3a1ffef53b';
    const amount = 1049500000000

    const getCoinInfo = function (parentCoinInfo, puzzleHash, amount) {
      const a = Buffer.from(parentCoinInfo, 'hex')
      const b = Buffer.from(puzzleHash, 'hex')
      let amountHex = amount.toString(16);
      if (amountHex.length % 2 == 1) {
        amountHex = '0' + amountHex
      }
      const c = Buffer.from(amountHex, 'hex');

      const d = Buffer.concat([a, b, c], a.length + b.length + c.length);
      const hash = createHash('sha256');
      hash.update(d);
      return hash.digest('hex')
    }

    console.log(getCoinInfo(parentCoinInfo, puzzleHash, amount))

试了一下 这笔计算的金额的hex前面要再加2个0 .. 至于为什么 目前判断是如果amount转换的第一位是字母 需要再补2个0

所以以下是我的補0方法。

amountHex = '0'.repeat((Math.ceil(Math.log2(amount))+8>>3<<1)-amountHex.length) + amountHex

非常好用 已经用上了 感谢大佬 不过有个小疑问 为什么要先右移3位再左移1位而不是直接右移2位呢