Inter-contract communication tutorial. Ping calls Pong to retrieve a value, demonstrating cross-contract function calls in Solidity.
Key Facts
Description
A tutorial contract from Cyrus Adkisson's solidity-baby-steps series demonstrating inter-contract communication. Ping stores a reference to a Pong contract and can call getPongvalTransactional() on it to retrieve and store the pong value locally.
The contract includes getPongvalRemote() which makes the cross-contract call, setPongAddress() to configure the target, and getter functions for both the local copy and the remote Pong address. Part of a numbered tutorial progression (contract #45) teaching Solidity fundamentals on mainnet during the Frontier era.
Cyrus deployed 5 copies of this contract between September and October 2015, each configured with a different Pong address.
Source Verified
Exact creation bytecode match. Author Cyrus Adkisson published source at https://github.com/cyrusadkisson/solidity-baby-steps/blob/master/contracts/45_ping.sol. Batch-matched against 357 deploy TXs from deployer 0xcf684dfb8304729355b58315e8019b1aa2ad1bac.
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology and exact bytecode matching.
View Verification ProofShow source code (Solidity)
// Contracts can get non-constant return values from functions in other contracts. (Whereas you can't from web3/geth.)
// These two contracts are meant to test this. Like so:
// 1. Deploy Pong with a pongval.
// 2. Deploy Ping, giving it the address of Pong.
// 3. Call Ping.getPongvalRemote() using a sendTransaction...
// 4. ... which retreives the value of pongval from Pong.
// 5. If successful Ping.getPongval() should return the value from step 1.
contract PongvalRetriever {
int8 pongval_tx_retrieval_attempted = 0;
function getPongvalTransactional() public returns (int8){ // tells Ping how to interact with Pong.
pongval_tx_retrieval_attempted = -1;
return pongval_tx_retrieval_attempted;
}
}
contract Ping is PongvalRetriever {
int8 pongval;
PongvalRetriever pvr;
address creator;
/*********
Step 2: Deploy Ping, giving it the address of Pong.
*********/
function Ping(PongvalRetriever _pongAddress)
{
creator = msg.sender;
pongval = -1;
pvr = _pongAddress;
}
/*********
Step 3: Transactionally retrieve pongval from Pong.
*********/
function getPongvalRemote()
{
pongval = pvr.getPongvalTransactional();
}
/*********
Step 5: Get pongval (which was previously retrieved from Pong via transaction)
*********/
function getPongvalConstant() constant returns (int8)
{
return pongval;
}
// -----------------------------------------------------------------------------------------------------------------
/*********
Functions to get and set pongAddress just in case
*********/
function setPongAddress(PongvalRetriever _pongAddress)
{
pvr = _pongAddress;
}
function getPongAddress() constant returns (address)
{
return pvr;
}
/****
For double-checking this contract's address
****/
function getAddress() returns (address)
{
return this;
}
/*********
Standard kill() function to recover funds
*********/
function kill()
{
if (msg.sender == creator)
suicide(creator); // kills this contract and sends remaining funds back to creator
}
}
// See Pong for deployment/use.