Merge ElementsProject/elements#993: [elements-0.18] Support supplying contract hash to issueasset RPC

8b9791fa0e Support supplying contract hash to issueasset RPC (Steven Roose)

Pull request description:

  Relating https://github.com/ElementsProject/elements/issues/985.

  Needs forward port.

Top commit has no ACKs.

Tree-SHA512: e30ce7f590a5d9e8aa37b4cccb4e69fa2c62adbc28a7e67e9a91b9cff081c54bb2e300ccb6e3c692719a8ec858bd32e32445d4040e19d1affd32dae5cc0462fc
This commit is contained in:
Steven Roose 2021-05-10 18:36:11 +02:00
commit 73cf2f5e6f
No known key found for this signature in database
GPG key ID: 2F2A88D7F8D68E87
4 changed files with 21 additions and 8 deletions

View file

@ -6133,16 +6133,16 @@ UniValue issueasset(const JSONRPCRequest& request)
return NullUniValue;
}
if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
throw std::runtime_error(
RPCHelpMan{"issueasset",
"\nCreate an asset. Must have funds in wallet to do so. Returns asset hex id.\n"
"For more fine-grained control such as non-empty contract-hashes to commit\n"
"to an issuance policy, see `rawissueasset` RPC call.\n",
"For more fine-grained control such as multiple issuances, see `rawissueasset` RPC call.\n",
{
{"assetamount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "Amount of asset to generate. Note that the amount is BTC-like, with 8 decimal places."},
{"tokenamount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "Amount of reissuance tokens to generate. Note that the amount is BTC-like, with 8 decimal places. These will allow you to reissue the asset if in wallet using `reissueasset`. These tokens are not consumed during reissuance."},
{"blind", RPCArg::Type::BOOL , /* default */ "true", "Whether to blind the issuances."},
{"contract_hash", RPCArg::Type::STR_HEX, /* default */ "0000...0000", "Contract hash that is put into issuance definition. Must be 32 bytes worth in hex string form. This will affect the asset id."},
},
RPCResult{
"{ (json object)\n"
@ -6174,6 +6174,12 @@ UniValue issueasset(const JSONRPCRequest& request)
bool blind_issuances = request.params.size() < 3 || request.params[2].get_bool();
// Check for optional contract to hash into definition
uint256 contract_hash;
if (request.params.size() >= 4) {
contract_hash = ParseHashV(request.params[3], "contract_hash");
}
if (!pwallet->IsLocked())
pwallet->TopUpKeyPool();
@ -6205,13 +6211,14 @@ UniValue issueasset(const JSONRPCRequest& request)
CAsset dummyasset;
IssuanceDetails issuance_details;
issuance_details.blind_issuance = blind_issuances;
issuance_details.contract_hash = contract_hash;
CTransactionRef tx_ref = SendGenerationTransaction(GetScriptForDestination(asset_dest), asset_dest_blindpub, GetScriptForDestination(token_dest), token_dest_blindpub, nAmount, nTokens, &issuance_details, *locked_chain, pwallet);
// Calculate asset type, assumes first vin is used for issuance
CAsset asset;
CAsset token;
assert(!tx_ref->vin.empty());
GenerateAssetEntropy(issuance_details.entropy, tx_ref->vin[0].prevout, uint256());
GenerateAssetEntropy(issuance_details.entropy, tx_ref->vin[0].prevout, issuance_details.contract_hash);
CalculateAsset(asset, issuance_details.entropy);
CalculateReissuanceToken(token, issuance_details.entropy, blind_issuances);

View file

@ -3448,12 +3448,12 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
uint256 entropy;
CAsset asset;
CAsset token;
//TODO take optional contract hash
// Initial issuance always uses vin[0]
GenerateAssetEntropy(entropy, txNew.vin[0].prevout, uint256());
GenerateAssetEntropy(entropy, txNew.vin[0].prevout, issuance_details->contract_hash);
CalculateAsset(asset, entropy);
CalculateReissuanceToken(token, entropy, issuance_details->blind_issuance);
CScript blindingScript(CScript() << OP_RETURN << std::vector<unsigned char>(txNew.vin[0].prevout.hash.begin(), txNew.vin[0].prevout.hash.end()) << txNew.vin[0].prevout.n);
txNew.vin[0].assetIssuance.assetEntropy = issuance_details->contract_hash;
// We're making asset outputs, fill out asset type and issuance input
if (asset_index != -1) {
txNew.vin[0].assetIssuance.nAmount = txNew.vout[asset_index].nValue;

View file

@ -693,7 +693,11 @@ struct CoinSelectionParams
struct IssuanceDetails {
bool issuing = false;
// Indicated fields.
bool blind_issuance = true;
uint256 contract_hash;
// Calculated fields.
CAsset reissuance_asset;
CAsset reissuance_token;
uint256 entropy;

View file

@ -109,7 +109,8 @@ class IssuanceTest(BitcoinTestFramework):
assert_equal(len(self.nodes[0].listissuances()), 0)
# Unblinded issuance of asset
issued = self.nodes[0].issueasset(1, 1, False)
contract_hash = "deadbeef"*8
issued = self.nodes[0].issueasset(1, 1, False, contract_hash)
balance = self.nodes[0].getwalletinfo()["balance"]
assert_equal(balance[issued["asset"]], 1)
assert_equal(balance[issued["token"]], 1)
@ -119,7 +120,8 @@ class IssuanceTest(BitcoinTestFramework):
self.nodes[0].generate(1)
self.sync_all()
issued2 = self.nodes[0].issueasset(2, 1)
contract_hash = "deadbeee"*8
issued2 = self.nodes[0].issueasset(2, 1, True, contract_hash)
test_asset = issued2["asset"]
assert_equal(self.nodes[0].getwalletinfo()['balance'][test_asset], Decimal(2))
node1balance = self.nodes[1].getwalletinfo()['balance']