Add calculateasset RPC

This commit is contained in:
Andrew Chow 2020-07-15 15:09:46 -04:00
parent 79c4a9901b
commit bdfcb436b7
3 changed files with 69 additions and 0 deletions

View file

@ -229,6 +229,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "sendtoaddress", 10, "ignoreblindfail" },
{ "createrawtransaction", 4, "output_assets" },
{ "createpsbt", 4, "output_assets" },
{ "calculateasset", 1, "vout" },
{ "calculateasset", 3, "blind_reissuance" },
};
// clang-format on

View file

@ -3026,6 +3026,56 @@ static RPCHelpMan rawreissueasset()
};
}
static RPCHelpMan calculateasset()
{
return RPCHelpMan{"calculateasset",
"\nCalculate the asset tags and reissuance asset tags for a given prevout and contract hash\n",
{
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Transaction id of the output that will be spent for this issuance."},
{"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "Output index of the output that will be spent for this issuance."},
{"asset_entropy", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "Additional asset entropy to be included in the asset tag. This is the contract hash."},
{"blind_reissuance", RPCArg::Type::STR_HEX, /* default */ "true", "Whether the reissuance asset tag will be blinded"},
},
RPCResult{
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR_HEX, "asset_tag", "Calculated asset tag."},
{RPCResult::Type::STR_HEX, "reissuance_asset_tag", "Asset tag for the reissuance tokens."},
{RPCResult::Type::STR_HEX, "final_asset_entropy", "The calculated asset entropy that is needed for reissuance."},
},
},
RPCExamples{""},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VNUM, UniValue::VSTR, UniValue::VBOOL}, true);
uint256 txid = ParseHashV(request.params[0], "txid");
uint32_t vout = request.params[1].get_int();
uint256 asset_entropy;
if (!request.params[2].isNull()) {
asset_entropy = ParseHashV(request.params[2], "asset_entropy");
}
bool blind_reissuance = request.params[3].isNull() ? true : request.params[3].get_bool();
uint256 entropy;
CAsset asset;
CAsset token;
COutPoint outpoint(txid, vout);
GenerateAssetEntropy(entropy, outpoint, asset_entropy);
CalculateAsset(asset, entropy);
CalculateReissuanceToken(token, entropy, blind_reissuance);
UniValue out(UniValue::VOBJ);
out.pushKV("asset_tag", asset.GetHex());
out.pushKV("reissuance_asset_tag", token.GetHex());
out.pushKV("final_asset_entropy", entropy.GetHex());
return out;
},
};
}
// END ELEMENTS
//
@ -3058,6 +3108,7 @@ static const CRPCCommand commands[] =
{ "rawtransactions", "rawissueasset", &rawissueasset, {"transaction","issuances"}},
{ "rawtransactions", "rawreissueasset", &rawreissueasset, {"transaction","reissuances"}},
{ "rawtransactions", "rawblindrawtransaction", &rawblindrawtransaction, {"hexstring","inputamountblinders","inputamounts","inputassets","inputassetblinders","totalblinder","ignoreblindfail"} },
{ "rawtransactions", "calculateasset", &calculateasset, {"txid", "vout", "asset_entropy", "blind_reissuance"} },
};
// clang-format on
for (const auto& c : commands) {

View file

@ -324,22 +324,34 @@ class IssuanceTest(BitcoinTestFramework):
issued_tx = self.nodes[2].rawissueasset(funded_tx, [{"asset_amount":1, "asset_address":nonblind_addr}])[0]["hex"]
decode_tx = self.nodes[0].decoderawtransaction(issued_tx)
id_set.add(decode_tx["vin"][0]["issuance"]["asset"])
calc_asset = self.nodes[0].calculateasset(decode_tx["vin"][0]["txid"], decode_tx["vin"][0]["vout"])
assert_equal(calc_asset["final_asset_entropy"], decode_tx["vin"][0]["issuance"]["assetEntropy"])
assert_equal(calc_asset["asset_tag"], decode_tx["vin"][0]["issuance"]["asset"])
# Again with 00..00 argument, which match the no-argument case
issued_tx = self.nodes[2].rawissueasset(funded_tx, [{"asset_amount":1, "asset_address":nonblind_addr, "contract_hash":"00"*32}])[0]["hex"]
decode_tx = self.nodes[0].decoderawtransaction(issued_tx)
id_set.add(decode_tx["vin"][0]["issuance"]["asset"])
assert_equal(len(id_set), 1)
calc_asset = self.nodes[0].calculateasset(decode_tx["vin"][0]["txid"], decode_tx["vin"][0]["vout"], "00"*32)
assert_equal(calc_asset["final_asset_entropy"], decode_tx["vin"][0]["issuance"]["assetEntropy"])
assert_equal(calc_asset["asset_tag"], decode_tx["vin"][0]["issuance"]["asset"])
# Random contract string should again differ
issued_tx = self.nodes[2].rawissueasset(funded_tx, [{"asset_amount":1, "asset_address":nonblind_addr, "contract_hash":"deadbeef"*8}])[0]["hex"]
decode_tx = self.nodes[0].decoderawtransaction(issued_tx)
id_set.add(decode_tx["vin"][0]["issuance"]["asset"])
assert_equal(len(id_set), 2)
calc_asset = self.nodes[0].calculateasset(decode_tx["vin"][0]["txid"], decode_tx["vin"][0]["vout"], "deadbeef"*8)
assert_equal(calc_asset["final_asset_entropy"], decode_tx["vin"][0]["issuance"]["assetEntropy"])
assert_equal(calc_asset["asset_tag"], decode_tx["vin"][0]["issuance"]["asset"])
issued_tx = self.nodes[2].rawissueasset(funded_tx, [{"asset_amount":1, "asset_address":nonblind_addr, "contract_hash":"deadbeee"*8}])[0]["hex"]
decode_tx = self.nodes[0].decoderawtransaction(issued_tx)
id_set.add(decode_tx["vin"][0]["issuance"]["asset"])
assert_equal(len(id_set), 3)
calc_asset = self.nodes[0].calculateasset(decode_tx["vin"][0]["txid"], decode_tx["vin"][0]["vout"], "deadbeee"*8)
assert_equal(calc_asset["final_asset_entropy"], decode_tx["vin"][0]["issuance"]["assetEntropy"])
assert_equal(calc_asset["asset_tag"], decode_tx["vin"][0]["issuance"]["asset"])
# Finally, append an issuance on top of an already-"issued" raw tx
# Same contract, different utxo being spent results in new asset type
@ -348,6 +360,10 @@ class IssuanceTest(BitcoinTestFramework):
decode_tx = self.nodes[0].decoderawtransaction(issued_tx)
id_set.add(decode_tx["vin"][1]["issuance"]["asset"])
assert_equal(len(id_set), 4)
calc_asset = self.nodes[0].calculateasset(decode_tx["vin"][1]["txid"], decode_tx["vin"][1]["vout"], None, False)
assert_equal(calc_asset["final_asset_entropy"], decode_tx["vin"][1]["issuance"]["assetEntropy"])
assert_equal(calc_asset["asset_tag"], decode_tx["vin"][1]["issuance"]["asset"])
assert_equal(calc_asset["reissuance_asset_tag"], decode_tx["vin"][1]["issuance"]["token"])
# This issuance should not have changed
id_set.add(decode_tx["vin"][0]["issuance"]["asset"])
assert_equal(len(id_set), 4)