Skip to Content
Courses

Item Smart Contract

Let’s add another smart contract:

pragma solidity ^0.6.0; import "./ItemManager.sol"; contract Item { uint public priceInWei; uint public paidWei; uint public index; ItemManager parentContract; constructor(ItemManager _parentContract, uint _priceInWei, uint _index) public { priceInWei = _priceInWei; index = _index; parentContract = _parentContract; } receive() external payable { require(msg.value == priceInWei, "We don't support partial payments"); require(paidWei == 0, "Item is already paid!"); paidWei += msg.value; (bool success, ) = address(parentContract).call{value:msg.value}(abi.encodeWithSignature("triggerPayment(uint256)", index)); require(success, "Delivery did not work"); } fallback () external { } }
Solidity Changes

Note that call.value(msg.value)(abi.encodeWithSignature("triggerPayment(uint256)",Ā index)), due to changes at Solidity version 6.4 it is recommended it should be changed to call{value:msg.value}(abi.encodeWithSignature("triggerPayment(uint256)",Ā index)).

And change the ItemManager Smart Contract to use the Item Smart Contract instead of the Struct only:

pragma solidity ^0.6.0; import "./Item.sol"; contract ItemManager { struct S_Item { Item _item; ItemManager.SupplyChainSteps _step; string _identifier; } mapping(uint => S_Item) public items; uint index; enum SupplyChainSteps {Created, Paid, Delivered} event SupplyChainStep(uint _itemIndex, uint _step, address _address); function createItem(string memory _identifier, uint _priceInWei) public { Item item = new Item(this, _priceInWei, index); items[index]._item = item; items[index]._step = SupplyChainSteps.Created; items[index]._identifier = _identifier; emit SupplyChainStep(index, uint(items[index]._step), address(item)); index++; } function triggerPayment(uint _index) public payable { Item item = items[_index]._item; require(address(item) == msg.sender, "Only items are allowed to update themselves"); require(item.priceInWei() == msg.value, "Not fully paid yet"); require(items[_index]._step == SupplyChainSteps.Created, "Item is further in the supply chain"); items[_index]._step = SupplyChainSteps.Paid; emit SupplyChainStep(_index, uint(items[_index]._step), address(item)); } function triggerDelivery(uint _index) public { require(items[_index]._step == SupplyChainSteps.Paid, "Item is further in the supply chain"); items[_index]._step = SupplyChainSteps.Delivered; emit SupplyChainStep(_index, uint(items[_index]._step), address(items[_index]._item)); } }

Now with this we just have to give a customer the address of the Item Smart Contract created during ā€œcreateItemā€ and he will be able to pay directly by sending X Wei to the Smart Contract. But the smart contract isn’t very secure yet. We need some sort of owner functionality.

Last updated on