pragma solidity ^0.4.18;
contract MyDeal {
/// The seller's address
address public owner;
/// The buyer's address part on this contract
address public buyerAddr;
/// The Buyer struct
struct Buyer {
address addr;
string name;
bool init;
}
/// The Order struct
struct Order {
string goods;
uint quantity;
uint number;
uint price;
uint safepay;
uint deliveryDate;
bool init;
}
/// The Invoice struct (facture)
struct Invoice {
uint orderno;
uint number;
bool init;
}
/// The mapping to store orders
mapping (uint => Order) orders;
/// The mapping to store invoices
mapping (uint => Invoice) invoices;
/// The sequence number of orders
uint public orderseq;
/// The sequence number of invoices
uint public invoiceseq;
/// Event triggered for every registered buyer
event BuyerRegistered(address buyer, string name);
/// Event triggered for every new order
event OrderSent(address buyer, string goods, uint quantity, uint orderno);
/// Event triggerd when the order gets valued and wants to know the value of the payment
event PriceSent(address buyer, uint orderno, uint price);
/// Event trigger when the buyer performs the safepay
event SafepaySent(address buyer, uint orderno, uint value, uint now);
/// Event triggered when the seller sends the invoice
event InvoiceSent(address buyer, uint invoiceno, uint orderno, uint delivery_date);
/// Event triggered when the seller delives the order
event OrderDelivered(address buyer, uint invoiceno, uint orderno, uint real_delivey_date,
address owner);
/// The smart contract's constructor
constructor(address _buyerAddr) public {
/// The seller is the contract's owner
owner = msg.sender;
buyerAddr = _buyerAddr;
}
///getters
function getOwner() view public returns (address) {
return owner;
}
function getBuyer() view public returns (address) {
return buyerAddr;
}
function getInvoiceseq() view public returns (uint) {
return invoiceseq;
}
function getOrderseq() view public returns (uint) {
return orderseq;
}
function getMsgSender() view public returns (address) {
return msg.sender;
}
///To get field values listen to OrderSent event.
function sendOrder(string goods, uint quantity) payable public {
/// Accept orders just from buyer
require(msg.sender == buyerAddr);
/// Increment the order sequence
orderseq++;
/// Create the order register
orders[orderseq] = Order(goods, quantity, orderseq, 0, 0, 0, true);
/// Trigger the event
emit OrderSent(msg.sender, goods, quantity, orderseq);
}
/// The function to query orders by number
/// Constant functions returns custom fields
function queryOrder(uint number) constant public returns (address buyer, string goods, uint quantity, uint price, uint safepay) {
/// Validate the order number
require(orders[number].init);
/// Return the order data
return(buyerAddr, orders[number].goods, orders[number].quantity, orders[number].price, orders[number].safepay);
}
/// The function to send the price to pay for order
function sendPrice(uint orderno, uint price) payable public {
/// Only the owner can use this function
require(msg.sender == owner);
/// Validate the order number
require(orders[orderno].init);
/// Update the order price
orders[orderno].price = price;
/// Trigger the event
emit PriceSent(buyerAddr, orderno, price);
}
/// The function to send the value of order's price
/// This value will be blocked until the delivery of order
/// requires fee
function sendSafepay(uint orderno) payable public {
/// Validate the order number
require(orders[orderno].init);
/// Just the buyer can make safepay
require(buyerAddr == msg.sender);
/// The order's value must equal to msg.value
require((orders[orderno].price) == msg.value);
orders[orderno].safepay = msg.value;
emit SafepaySent(msg.sender, orderno, msg.value, now);
}
/// The function to send the invoice data
/// requires fee
function sendInvoice(uint orderno, uint delivery_date) payable public {
/// Validate the order number
require(orders[orderno].init);
/// Just the seller can send the invoice
require(owner == msg.sender);
invoiceseq++;
/// Create then Invoice instance and store it
invoices[invoiceseq] = Invoice(orderno, invoiceseq, true);
/// Update the shipment data
orders[orderno].deliveryDate = delivery_date;
/// Trigger the event
emit InvoiceSent(buyerAddr, invoiceseq, orderno, delivery_date);
}
/// The function to get the sent invoice
/// requires no fee
function getInvoice(uint invoiceno) constant public returns (address buyer, uint orderno, uint delivery_date){
/// Validate the invoice number
require(invoices[invoiceno].init);
Invoice storage _invoice = invoices[invoiceno];
Order storage _order = orders[_invoice.orderno];
return (buyerAddr, _order.number, _order.deliveryDate);
}
/// The function to mark an order as delivered
function delivery(uint invoiceno, uint timestamp) payable public {
/// Validate the invoice number
require(invoices[invoiceno].init);
Invoice storage _invoice = invoices[invoiceno];
Order storage _order = orders[_invoice.orderno];
/// Just the seller (owner) can call this function
require(msg.sender == owner);
emit OrderDelivered(buyerAddr, invoiceno, _order.number, timestamp, owner);
/// Payout the Order to the seller
owner.transfer(_order.safepay);
}
function health() pure public returns (string) {
return "running";
}
}
Code to deploy and load contract
public MyContract createContract(MyContract newContract) throws Exception { buyerAddr = template.getForObject(url, String.class); LOGGER.info("Buyer adress is here : {} ", buyerAddr);
contract = MyDeal.deploy(web3j, credentialsSeller, GAS_PRICE, GAS_LIMIT, buyerAddr).send();
newContract.setBuyer(buyerAddr);
newContract.setAddress(contract.getContractAddress());
newContract.setSeller(credentialsSeller.getAddress());
contracts.add(contract.getContractAddress());
LOGGER.info("Address={} added to contracts list",contract.getContractAddress());
LOGGER.info("New contract deployed: address={}", contract.getContractAddress());
Optional<TransactionReceipt> tr = contract.getTransactionReceipt();
if (tr.isPresent()) {
LOGGER.info("Transaction receipt: hash={}, from={}, to={}, gas={}", tr.get().getTransactionHash(), tr.get().getFrom(), tr.get().getTo(), tr.get().getGasUsed().intValue());
}
/*Subscription s = contract.buyerRegisteredEventObservable(DefaultBlockParameterName.LATEST, DefaultBlockParameterName.LATEST)
.subscribe(evento ->{
LOGGER.info("Event Received");
}, Throwable::printStackTrace);
s.unsubscribe();*/
Thread.sleep(500);
return newContract;
}
public Boolean loadContract() throws Exception {
MyDeal loadedContract = MyDeal.load(contract.getContractAddress(), web3j, credentialsSeller, GAS_PRICE, GAS_LIMIT );
//LOGGER.info("orderseq is : {}",loadedContract.getOrderseq().send());
return loadedContract.isValid();
}`