Skip to content

Commit

Permalink
Merge pull request #199 from qtumproject/neil/fix-vout-overflow
Browse files Browse the repository at this point in the history
Neil/fix vout overflow
  • Loading branch information
Earlz authored Jun 27, 2017
2 parents 62a6952 + b540248 commit d93a783
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 4 deletions.
55 changes: 55 additions & 0 deletions qa/rpc-tests/dupe-contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.script import *
from test_framework.mininode import *
from test_framework.blocktools import *
from test_framework.qtum import *
import sys
import io

class QtumDupeContractTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.num_nodes = 1

def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [[]])
self.node = self.nodes[0]

def run_test(self):
self.node.generate(10+COINBASE_MATURITY)
tx = CTransaction()
tx.vin = [make_vin(self.node, 6*COIN)]
tx.vout = []

# First we append two OP_CREATE outputs (vout = 0, 1 (mod 256))
tx.vout.append(CTxOut(0, CScript([1, 1000000, 1, bytes.fromhex("60606040523415600b57fe5b5b60398060196000396000f30060606040525b600b5b5b565b0000a165627a7a72305820e3bed070fd3a81dd00e02efd22d18a3b47b70860155d6063e47e1e2674fc5acb0029"), OP_CREATE])))
tx.vout.append(CTxOut(0, CScript([1, 1000000, 1, bytes.fromhex("60606040523415600b57fe5b5b60398060196000396000f30060606040525b600b5b5b565b0000a165627a7a72305820e3bed070fd3a81dd00e02efd22d18a3b47b70860155d6063e47e1e2674fc5acb0029"), OP_CREATE])))

# Now we append 255 vouts that spend no gas
for _ in range(2, 256):
tx.vout.append(CTxOut(1000000, CScript([OP_TRUE])))

# Now we append another two more vouts that should create contracts (vout = 0, 1 (mod 256))
tx.vout.append(CTxOut(0, CScript([1, 1000000, 1, bytes.fromhex("60606040523415600b57fe5b5b60398060196000396000f30060606040525b600b5b5b565b0000a165627a7a72305820e3bed070fd3a81dd00e02efd22d18a3b47b70860155d6063e47e1e2674fc5acb0029"), OP_CREATE])))
tx.vout.append(CTxOut(0, CScript([1, 1000000, 1, bytes.fromhex("60606040523415600b57fe5b5b60398060196000396000f30060606040525b600b5b5b565b0000a165627a7a72305820e3bed070fd3a81dd00e02efd22d18a3b47b70860155d6063e47e1e2674fc5acb0029"), OP_CREATE])))

ret = self.node.signrawtransaction(bytes_to_hex_str(tx.serialize()))
self.node.sendrawtransaction(ret['hex'])
self.node.generate(1)

# This should result in 4 contracts being created.
assert_equal(len(self.node.listcontracts()), 4)





if __name__ == '__main__':
QtumDupeContractTest().main()
5 changes: 4 additions & 1 deletion src/qtum/qtumstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ void QtumState::addBalance(dev::Address const& _id, dev::u256 const& _amount)
dev::Address QtumState::createQtumAddress(dev::h256 hashTx, uint32_t voutNumber){
uint256 hashTXid(h256Touint(hashTx));
std::vector<unsigned char> txIdAndVout(hashTXid.begin(), hashTXid.end());
txIdAndVout.push_back(voutNumber);
std::vector<unsigned char> voutNumberChrs;
if (voutNumberChrs.size() < sizeof(voutNumber))voutNumberChrs.resize(sizeof(voutNumber));
std::memcpy(voutNumberChrs.data(), &voutNumber, sizeof(voutNumber));
txIdAndVout.insert(txIdAndVout.end(),voutNumberChrs.begin(),voutNumberChrs.end());

std::vector<unsigned char> SHA256TxVout(32);
CSHA256().Write(txIdAndVout.data(), txIdAndVout.size()).Finalize(SHA256TxVout.data());
Expand Down
10 changes: 7 additions & 3 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,12 +596,16 @@ UniValue createcontract(const JSONRPCRequest& request){
std::vector<unsigned char> SHA256TxVout(32);
vector<unsigned char> contractAddress(20);
vector<unsigned char> txIdAndVout(wtx.GetHash().begin(), wtx.GetHash().end());
unsigned char nOut=0;
uint32_t voutNumber=0;
BOOST_FOREACH(const CTxOut& txout, wtx.tx->vout) {
if(txout.scriptPubKey.HasOpCreate()){
txIdAndVout.push_back(nOut);
std::vector<unsigned char> voutNumberChrs;
if (voutNumberChrs.size() < sizeof(voutNumber))voutNumberChrs.resize(sizeof(voutNumber));
std::memcpy(voutNumberChrs.data(), &voutNumber, sizeof(voutNumber));
txIdAndVout.insert(txIdAndVout.end(),voutNumberChrs.begin(),voutNumberChrs.end());
break;
}
nOut++;
voutNumber++;
}
CSHA256().Write(txIdAndVout.data(), txIdAndVout.size()).Finalize(SHA256TxVout.data());
CRIPEMD160().Write(SHA256TxVout.data(), SHA256TxVout.size()).Finalize(contractAddress.data());
Expand Down

0 comments on commit d93a783

Please sign in to comment.