1 #include "crosschain.h"
2 #include "importcoin.h"
7 #include "primitives/transaction.h"
10 CTransaction MakeImportCoinTransaction(const TxProof proof, const CTransaction burnTx, const std::vector<CTxOut> payouts)
12 std::vector<uint8_t> payload = E_MARSHAL(ss << EVAL_IMPORTCOIN);
13 CMutableTransaction mtx;
14 mtx.vin.push_back(CTxIn(COutPoint(burnTx.GetHash(), 10e8), CScript() << payload));
16 auto importData = E_MARSHAL(ss << proof; ss << burnTx);
17 mtx.vout.insert(mtx.vout.begin(), CTxOut(0, CScript() << OP_RETURN << importData));
18 return CTransaction(mtx);
22 CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector<CTxOut> payouts)
24 std::vector<uint8_t> opret = E_MARSHAL(ss << VARINT(targetCCid);
26 ss << SerializeHash(payouts));
27 return CTxOut(value, CScript() << OP_RETURN << opret);
31 bool UnmarshalImportTx(const CTransaction &importTx, TxProof &proof, CTransaction &burnTx,
32 std::vector<CTxOut> &payouts)
34 std::vector<uint8_t> vData;
35 GetOpReturnData(importTx.vout[0].scriptPubKey, vData);
36 if (importTx.vout.size() < 1) return false;
37 payouts = std::vector<CTxOut>(importTx.vout.begin()+1, importTx.vout.end());
38 return importTx.vin.size() == 1 &&
39 importTx.vin[0].scriptSig == (CScript() << E_MARSHAL(ss << EVAL_IMPORTCOIN)) &&
40 E_UNMARSHAL(vData, ss >> proof; ss >> burnTx);
44 bool UnmarshalBurnTx(const CTransaction &burnTx, std::string &targetSymbol, uint32_t *targetCCid, uint256 &payoutsHash)
46 std::vector<uint8_t> burnOpret;
47 if (burnTx.vout.size() == 0) return false;
48 GetOpReturnData(burnTx.vout.back().scriptPubKey, burnOpret);
49 return E_UNMARSHAL(burnOpret, ss >> VARINT(*targetCCid);
58 CAmount GetCoinImportValue(const CTransaction &tx)
62 std::vector<CTxOut> payouts;
63 if (UnmarshalImportTx(tx, proof, burnTx, payouts)) {
64 return burnTx.vout.size() ? burnTx.vout.back().nValue : 0;
71 * CoinImport is different enough from normal script execution that it's not worth
72 * making all the mods neccesary in the interpreter to do the dispatch correctly.
74 bool VerifyCoinImport(const CScript& scriptSig, TransactionSignatureChecker& checker, CValidationState &state)
76 auto pc = scriptSig.begin();
78 std::vector<uint8_t> evalScript;
81 if (!scriptSig.GetOp(pc, opcode, evalScript))
83 if (pc != scriptSig.end())
85 if (evalScript.size() == 0)
87 if (evalScript.begin()[0] != EVAL_IMPORTCOIN)
89 // Ok, all looks good so far...
90 CC *cond = CCNewEval(evalScript);
91 bool out = checker.CheckEvalCondition(cond, 1);
96 return f() ? true : state.Invalid(false, 0, "invalid-coin-import");
100 void AddImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs, int nHeight)
102 uint256 burnHash = importTx.vin[0].prevout.hash;
103 CCoinsModifier modifier = inputs.ModifyCoins(burnHash);
104 modifier->nHeight = nHeight;
105 modifier->nVersion = 1;
106 modifier->vout.push_back(CTxOut(0, CScript() << OP_0));
110 void RemoveImportTombstone(const CTransaction &importTx, CCoinsViewCache &inputs)
112 uint256 burnHash = importTx.vin[0].prevout.hash;
113 inputs.ModifyCoins(burnHash)->Clear();
117 int ExistsImportTombstone(const CTransaction &importTx, const CCoinsViewCache &inputs)
119 uint256 burnHash = importTx.vin[0].prevout.hash;
120 return inputs.HaveCoins(burnHash);