It is very possible to use the Oraclize service with testrpc alongside truffle.
Firstly, you need to follow the naming convention of contract filenames in truffle. As per their docs:
Truffle expects your contract files to define contracts that match their filenames exactly
Therefore you should download the Oraclize API from the Oraclize github repo, here's a specific link to the file oraclizeAPI_0.4.sol. Download this to the truffle contracts folder of your working directory, and rename the file to usingOraclize.sol
. This is required so at compilation time, truffle knows which specific contract to compile from within the file. The other alternative is to directly paste all of the API into the required contract, but adding and renaming the API itself is likely the most elegant solution I'm aware of at the moment.
Now you will be able to import the API on your other contracts within that folder by including import "usingOraclize.sol"
at the beginning of them, and then specifying its inheritance on the proper contract within, assuming the name of the example contract you need the API in is named myContract
, the inheritance method should looks like
contract myContract is usingOraclize {
// your code
}
The next step is making it so that your private testrpc chain is able to communicate with the Oraclize service, giving it the ability to send requests and receive the results back. For this, you will need the ethereum-bridge. Git clone that repository into a separate folder somewhere. What the bridge will do is, as its name suggest, setup a bridge for you between the Oraclize service and your blockchain while it runs.
Once ethereum-bridge is properly set-up, testrpc should be configured to use a static set of addresses, as the bridge will be dependent upon a specified address for deploying its required contracts on your private testrpc chain, therefore if you want those addresses to stay constant, between testrpc runs, you should be running testrpc with some re-usable addresses. You can do this by adding the --mnemonic
flag when starting it, and using the same mnemonic phrase over when restarting testrpc, to ensure it generates the same Oraclize OAR (OraclizeAddressResolver), which you will need to use in the next step.
Now, we will need to find out the OAR that gets generated by the bridge.
- Start testrpc using a specific mnemonic phrase, and take note of the index of the last available account, (you can use any for this, but I recommend the last one, as it's an account that shouldn't be used in tests, also make sure enough other accounts were generated for you to be able to do tests using). Here's an example startup parameter:
testrpc --mnemonic "my test example" --accounts 50
Since 50 accounts are generated, the last address' index is 49.
- Run the eth-bridge, and get the OAR that is generated using this testrpc chain. I am assuming testrpc is running on the default RPC host:port of localhost:8545, if not you will need additional paramaters. Go to the root directory where ethereum-bridge is, and run the following command in a terminal.
node bridge -a 49
The following part of step 2 only needs to be done on your first-run
Now wait, until you see the line:
Please add this line to your contract constructor:
OAR = OraclizeAddrResolverI(0x145437eac36aeacee0c135c9015fff316ba938ed);
Your address should of course be different, as you'd be using a different mnemonic phrase. Add that specific line, right at the beginning of your myContract
constructor so that it looks like this:
contract myContract is usingOraclize {
function myContract() {
OAR = OraclizeAddrResolverI(0x145437eac36aeacee0c135c9015fff316ba938ed);
// rest of your constructor code
}
// your code
}
- Now you are ready to begin compilation on truffle and making any tests you need for it, just ensure you always run steps 1 and 2 with the same parameters, and you won't have to change the OAR from within the contracts! (Do remember to remove the OAR variable from your constructor before production, this is just for testing, in production it will automatically fetch the OAR depending on the chain you're running it, currently the Mainnet, Ropsten, and browser-solidity VM environment are supported.)