Order Platform
Endless Go SDK Quick Start
1. Order Platform Move Contract
1.1 Contract Overview
The contract provides a decentralized framework for creating and managing orders within an e-commerce ecosystem. It defines the complete lifecycle of an order, from creation to completion, including payment, shipping, and cancellation. The system is built on the Endless blockchain, utilizing EndlessCoin for payments and a table-based storage system for scalability.
1.2 Core Concepts
1.2.1 Order Lifecycle (State Machine)
The core of the contract is a state machine that represents the lifecycle of an order. Each order progresses through a series of statuses, and transitions are governed by specific rules and function calls.
The statuses are defined as constants:
STATUS_PENDING_PAYMENT(0): The initial state after an order is created. Awaiting payment from the buyer.STATUS_PAID(1): The buyer has successfully transferred the funds to the seller.STATUS_SHIPPED(2): The seller has marked the order as shipped.STATUS_COMPLETED(3): The buyer has confirmed receipt of the item. (Note: The function for this is currently commented out but is part of the intended design).STATUS_CANCELLED(4): The order has been cancelled by either the buyer or the seller under specific conditions.
A typical successful order flow is: PENDING_PAYMENT -> PAID -> SHIPPED -> COMPLETED
1.2.2 Roles
There are two primary roles in this system:
Buyer: The user who creates and pays for the order.
Seller: The user who receives payment and ships the item.
Each state-changing function includes assertions to ensure that the transaction signer has the correct role for the intended action (e.g., only the buyer can pay, only the seller can ship).
1.2.3 Economy
All financial transactions are conducted using the native EndlessCoin(EDS). Prices and payments are specified in veins, the smallest unit of EndlessCoin, to ensure precision and avoid floating-point issues. 1 EDS = 100_000_000 Veins.
1.3 Data Structures (On-Chain State)
The contract's state is managed by two singleton resources, stored under the deployer's account (@order_platform).
1.3.1 Resources
OrderCounter:A singleton resource that ensures every order receives a unique, sequential ID.
next_order_id: u64: A counter that is incremented each time a new order is created.
Orders:A singleton resource that acts as the central repository for all orders.
orders: Table<u64, Order>: A scalable map (Table) that links a uniqueorder_id(u64) to its correspondingOrderstruct. This allows for efficient lookups, insertions, and modifications.
1.3.2 Structs
Order:The primary data structure representing an individual order. It has
storeanddropabilities, meaning it can be stored in global storage but cannot be copied.order_id: u64: Unique identifier.buyer: address: The address of the buyer.seller: address: The address of the seller.item_id: String: A string identifier for the product.quantity: u128: The number of items ordered.unit_price: u128: The price per item in Veins.total_price: u128: The calculated total price (quantity * unit_price).status: u8: The current status of the order, corresponding to the status constants.
OrderData:A read-only representation of an order's data. It has
copy,drop, andstoreabilities, making it suitable for returning from#[view]functions. Its structure mirrors theOrderstruct.
1.4 Events
The contract emits events at key points in the order lifecycle. This allows off-chain services, indexers, and user interfaces to monitor and react to on-chain activity without needing to query the state directly.
OrderCreatedEvent: Emitted whencreate_orderis successfully called.OrderPaidEvent: Emitted whenpay_orderis successfully called.OrderShippedEvent: Emitted whenship_orderis successfully called.OrderCancelledEvent: Emitted whencancel_orderis successfully called.OrderCompletedEvent: Emitted when an order is marked as complete.
1.5 Functions (Module API)
1.5.1 Initialization Function
init_module(deployer: &signer):A private function that must be called once by the module deployer to initialize the
OrderCounterandOrdersresources.It includes an assertion to prevent re-initialization.
1.5.2 Entry Functions (State-Changing)
create_order(...):Allows a
buyerto create a new order.It calculates the
total_price, assigns a neworder_id, stores theOrderstruct in theOrderstable, and emits anOrderCreatedEvent.
pay_order(...):Allows the
buyerto pay for an order that is in theSTATUS_PENDING_PAYMENT.Preconditions: The order must exist, the signer must be the buyer, the status must be
PENDING_PAYMENT, and the payment amount must match thetotal_price.It transfers
EndlessCoinfrom the buyer to the seller, updates the order status toSTATUS_PAID, and emits anOrderPaidEvent.
ship_order(...):Allows the
sellerto mark a paid order as shipped.Preconditions: The order must exist, the signer must be the seller, and the status must be
STATUS_PAID.It updates the order status to
STATUS_SHIPPEDand emits anOrderShippedEvent.
cancel_order(...):Allows a
buyerorsellerto cancel an order based on specific rules.Preconditions:
A
buyercan cancel if the status isPENDING_PAYMENTorPAID.A
sellercan cancel only if the status isPENDING_PAYMENT.The signer must be either the buyer or the seller.
It updates the order status to
STATUS_CANCELLEDand emits anOrderCancelledEvent.Note: This function does not currently handle refund logic for paid cancellations. This would be a required enhancement for a production system.
1.5.3 View Functions (Read-Only)
get_order_details(order_id: u64): OrderData:A public, read-only function that returns the
OrderDatafor a givenorder_id.It asserts that the order exists.
get_order_status(order_id: u64): u8:A public, read-only function that returns just the
statusof a givenorder_id.
1.6 Error Handling
The module defines a set of comprehensive error codes to provide clear reasons for transaction failures.
E_NOT_INITIALIZED(1): The module has not been initialized.E_ORDER_NOT_FOUND(2): The specifiedorder_iddoes not exist.E_INVALID_ORDER_STATUS(3): The action is not allowed in the order's current state.E_INSUFFICIENT_FUNDS(4): The buyer does not have enough coins to pay.E_SENDER_NOT_BUYER(5): The transaction was signed by an address other than the buyer's.E_SENDER_NOT_SELLER(6): The transaction was signed by an address other than the seller's.E_PAYMENT_AMOUNT_MISMATCH(7): The payment amount does not match the order's total price.E_COIN_TRANSFER_FAILED(9): A generic error for coin transfer failures.E_NOT_AUTHORIZED(10): The signer is neither the buyer nor the seller for a restricted action.
1.7 Future Enhancements
Implement
complete_order: Add the entry function to allow buyers to mark an order asSTATUS_COMPLETED.Refund on Cancellation: Implement logic in
cancel_orderto automatically refund the buyer if aPAIDorder is cancelled.Reputation System: Add a mechanism for buyers and sellers to rate each other after an order is completed.
Dispute Resolution: Introduce a mechanism for handling disputes, potentially involving a trusted third party or a decentralized arbitration process.
1.8 Deploy Contract
1.8.1 Create project folder
1.8.2 Create move contract folder
1.8.3 Init contract project
1.8.4 Implementing the contract according to the above design
The complete contract is in the file {path}\endless-orders\move\sources\orders.move
1.8.5 Craete contract deplay account
1.8.6 Modify contract address
Modify [addresses] field in {path}\endless-orders\move\Move.toml
"0xdcf462ef1bad8ed0901043126048acdbf6446f486eee2a38a12ddf8b727a2cc6"'s base58 format.
1.8.7 Deploy contract
Follow the prompts: type yes when asked for a Do you want to submit a transaction for a range of... and press Enter.
2. Use Go SDK to interact with contracts
Before you begin, please ensure that you have the Go language environment and VS Code installed on your system.
2.1 Install Go
Download Go: Visit the official Go download page, download and install the latest version of Go for your operating system.
Configure Environment Variables: The installer usually configures the environment variables automatically. If not, manually add the Go
bindirectory (e.g.,C:\Go\binor/usr/local/go/bin) to your system'sPATHenvironment variable.Verify Installation: Open a terminal or command prompt and enter the following command to verify that Go is installed correctly:
If you see the version number output, the installation was successful.
2.2 Install Visual Studio Code
Visit the official VS Code website to download and install the version suitable for your operating system.
2.2.1 Install the Go Extension
VS Code supports development in different languages through extensions. For Go, we need to install the official Go extension.
Open VS Code.
Click the Extensions icon in the sidebar or use the shortcut
Ctrl+Shift+X.Enter
Goin the search box.Find the official extension published by the Go Team at Google and click Install.

2.2..2 Install Go Development Tools
The Go extension relies on some command-line tools to provide advanced features like code completion, formatting, definition jumping, and debugging (e.g., gopls, dlv).
After installing the Go extension, a notification will usually appear in the bottom right corner suggesting you install these dependency tools. Click Install All.
If you miss the notification, you can also install them manually:
Open the Command Palette:
Ctrl+Shift+P(Windows/Linux) orCmd+Shift+P(macOS).Type
Go: Install/Update Toolsand press Enter.Check all the tools in the list, then click OK.
VS Code will automatically execute the
go installcommand in the terminal to install these tools. Please ensure your network can access Go's domains.
2.3 Create Your Go Project
2.3.1 Initialize a Go Module
Since Go 1.11, Go Modules are the official way to manage project dependencies. Run the following command in the project root directory to initialize a module:
After execution, a go.mod file will be generated in the directory.
2.3.2 Create the main.go File
Create a file named main.go in the project root directory and enter the following "Hello, World!" code:
2.3.3 Add endless-go-sdk and cobra
In order to call the endless on-chain contract and conveniently process command line instructions, we need to add dependencies endless-go-sdk and cobra.
To facilitate the processing of command line commands, we added cobra package.
2.3.4 Create project structure directories and files
main.go: program entry root.go: root Command order.go: All cli commands and parameter definitions and parsing of each command web3.go: All commands and interactions with on-chain contracts
2.3.5 Register root command
Definition a rootCmd in cmd/root.go
Then we can call its Execute() function in main.go as as follows
2.3.6 Create an account and faucet EDS on testnet
2.3.6.1 Create an account
An account is essentially a public-private key pair and an account address derived from them. We save the generated private key and account address locally, so that when needed, we can directly read the file and construct an account to interact with the chain.
1 Define and register the
Create accountcommand In cmd/order.go define and register the command, they call the corresponding specific implementation in web3/web3.go to complete the entire function.
2 Implement the
Create accountcommand
In this way, we have implemented a function to create an account and save it.
3 Create an account named alice
2.3.6.2 faucet EDS on testnet for alice
1 Define and register the
Faucet Accountcommand Add the following code to the cmd/order.go
Add faucetAccountCmd to init function.
2 Implement the
Faucet accountcommand In order to easy for loading of an account, we implement a function in web3/web3.go
To interact with the blockchain, you need to build an endless.Client object. The endless.Client provides a Faucet function, which can directly get a EDS on the test network. To send a transaction, you need to pass in the SequenceNumber of the account. The new account does not exist on the chain and has no SequenceNumber. Therefore, err = client.Faucet(*account) will directly report an error. In this case, you need to set the SequenceNumber of the account to 0.
At this point, all the functions of Faucet account are completed
3 Faucet EDS on testnet for alice
2.3.7 Call the function of the published contract
So far, we have not interacted with the contract we published. Now let's create an order using our contract.
2.3.7.1 Create order subcommand
We put all interactive commands with the orders contract to the order subcommand. First define a orderCmd in cmd/order.go
Then register orderCmd to rootCmd
2.3.7.2 Implement Create Order Command for order subcommand
1 Define and register
createOrderCmdfororderCmdin cmd/order.go
2 Define contract address and module address In endless, one address can publish multiple contracts, and each contract can be called a module. Such as 0x4 address is EndlessToken package. It contains Six modules, including
coin,collection,nft,property_map,royaltyandtoken. EndlessToken package
Define endless-orders address and orders module in web3/web3.go.
Use GetContractAddress to get the contract address
3 Implement
createOrderCmd
Serialize Arguments: The function's arguments (quantity, unitPrice, itemId) are serialized into the BCS (Binary Canonical Serialization) format, which is required by the Endless blockchain.
quantity and unitPrice are converted to u128.
itemId is serialized as a string.
Construct Entry Function Payload: It builds an endless.EntryFunction struct. This struct specifies the target smart contract to call,
Module: The contract's on-chain address (retrieved via GetContractAddress) and the module name (orders).
Function: The name of the function to call (create_order).
Args: The serialized arguments for the function call: seller's address, item ID, quantity, and unit price.
In this way, we have completed the function of creating orders on the chain.
4 Create an order on chain
Visit the Official Endless Scan Website,can find the event orders::OrderCreatedEvent,or you can Parse the UserTransaction returned by WaitForTransaction to extract this event. We can know the newly created order id is 1.
2.3.7.3 Implementing Other Order Subcommands
Similar to the order creation process described in 2.3.7.2, you can implement other commands other order commands such as order payment, order shipping, etc., The complete functional implementation is already in cmd/order.go and web3/web3.go in the latest code repository. It is important to note that when Go language json parses the field type of the returned object, sometimes the type it parses is not the type you expected. That is why when calling the view function get_order_status, its return value is converted to float64 in Go. For example, when calling the get_order_status view function, its return value is treated as a float64 in Go.
Last updated