A shipping escrow contract with public struct getters, late delivery penalties, and IPFS cargo documentation. Sibling of ShippingEscrow with added buyer/seller/
Key Facts
Description
An iteration on the ShippingEscrow contract deployed by the same developer minutes later on Jan 9, 2016. ShippingEscrow2 adds public getters for all three data structures (seller, cargo, buyer), giving external callers full visibility into the escrow state.
The contract manages a transaction between a seller and buyer for physical goods shipment. The seller creates the escrow with cargo details including name, description, origin and destination countries, a penalty rate for late delivery, and an IPFS hash for documentation. A buyer enters the agreement by calling agreement() with ETH payment. After a 3-day waiting period (259,200 seconds), the escrowed payment can be released to the seller. The arrival() function calculates late delivery penalties based on days past the shipped date.
Compared to its sibling ShippingEscrow (0x50fb8066), this version uses lowercase function names (escrow, releasePayment, arrival, agreement) rather than PascalCase, removes the internal Escrow() call from agreement(), and exposes the full EscrowData struct through a cargo() getter returning all 13 fields including two dynamic strings.
The deployer created two additional identical copies of this contract on the same day with different test data, suggesting active iteration on the escrow design.
Source Verified
Exact bytecode match (init + runtime). 800 bytes init + 2615 bytes constructor args. Runtime 2039 bytes. v0.1.5 through v0.1.7 all produce identical output. Two identical clones at 0xbfb62a95 and 0xaddDDbD2.
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)
contract ShippingEscrow2 {
struct Seller {
bytes32 name;
bytes32 company;
bytes32 id;
address addr;
}
struct EscrowData {
bytes32 cargoName;
string description;
bool quantity;
uint penaltyActive;
uint maxPenaltyDays;
bytes32 originCountry;
bytes32 destCountry;
uint createdAt;
uint shippedAt;
uint paymentAmount;
uint penaltyRate;
string ipfsHash;
bool isActive;
}
struct Buyer {
bytes32 name;
bytes32 company;
bytes32 id;
address addr;
bool isPaid;
}
Seller public seller;
EscrowData public cargo;
Buyer public buyer;
event paymentReleased(string message, uint amount);
event delayedShipment(string message, uint penaltyDays);
event newAgreement(string message, bytes32 sellerName, bytes32 buyerName);
function ShippingEscrow2(
bytes32 _sellerName,
bytes32 _sellerCompany,
bytes32 _sellerID,
bytes32 _cargoName,
string _description,
bool _quantity,
uint _penaltyActive,
uint _maxPenaltyDays,
bytes32 _originCountry,
bytes32 _destCountry,
uint _shippedAt,
uint _penaltyRate,
string _ipfsHash
) {
seller.name = _sellerName;
seller.company = _sellerCompany;
seller.id = _sellerID;
seller.addr = msg.sender;
cargo.cargoName = _cargoName;
cargo.description = _description;
cargo.quantity = _quantity;
cargo.penaltyActive = _penaltyActive;
cargo.maxPenaltyDays = _maxPenaltyDays;
cargo.originCountry = _originCountry;
cargo.destCountry = _destCountry;
cargo.shippedAt = _shippedAt;
cargo.penaltyRate = _penaltyRate;
cargo.ipfsHash = _ipfsHash;
cargo.isActive = false;
}
function agreement(bytes32 _buyerName, bytes32 _buyerCompany, bytes32 _buyerID) {
buyer.name = _buyerName;
buyer.company = _buyerCompany;
buyer.id = _buyerID;
buyer.addr = msg.sender;
cargo.paymentAmount = msg.value;
buyer.isPaid = false;
cargo.createdAt = block.timestamp;
cargo.isActive = true;
newAgreement("New Agreement between two Parties!", seller.name, buyer.name);
}
function escrow() {
if (buyer.isPaid) throw;
if (cargo.createdAt + 259200 >= block.timestamp) {
releasePayment();
}
}
function releasePayment() {
if (buyer.isPaid) throw;
seller.addr.send(cargo.paymentAmount);
buyer.isPaid = true;
paymentReleased("Payment released!", cargo.paymentAmount);
}
function arrival() {
uint timeDiff = block.timestamp - cargo.shippedAt;
uint daySeconds = 86400;
uint numDays = 0;
if (timeDiff >= daySeconds) {
numDays = timeDiff / daySeconds;
uint penalty = numDays * cargo.penaltyRate;
delayedShipment("The shipment has arrived late. Delay penalty will be charged.", penalty);
}
}
}