There is a flow I want to achieve in my dapp, and I would appreciate some opinion.
Flow:
User sees a list of products and picks one to buy it. The user has their metamask unlocked and has enough balance.
Setup:
Rails on the backend, React on the frontend, ganache-cli, truffle, metamask (web3js).
Database structure:
In the app's internal PostgresDB, there's a products
table. In the blockchain, there's a dynamic array products
like below:
Internal Postgres:
products
name
price
owner_id
owners
name
id
address
Blockchain (contract storage)
Product[] products
struct Product {
name
}
mapping(uint => address) public productIdToOwner;
mapping(uint => uint) public productIdToPrice;
The following function onBuy
runs when the user clicks "Buy this product" button:
onBuy = (product) => {
const { id, external_id, name, price, meta } = product
this.ContractInstance.methods.buy(external_id).send({
from: this.state.currentUserAddress,
gas: GAS_LIMIT,
value: web3.utils.toWei(price.toString(), "ether"),
}).then((receipt) => {
// What to do before getting a receipt?
console.log(receipt)
}).catch((err) => {
console.log(err.message)
})
}
Questions:
On the mainnet, how long does it take for me to get the receipt for the transaction? Is it sane to make the user wait on the same page after clicking the
onBuy
button with a loading wheel until the receipt arrives? If not, what's the conventional way to deal with this?Is my DB structure a reasonable way to connect to the blockchain? I am worried about data integrity (i.e. having to sync
address
field between my internal DB and the blockchain) but I find it useful to store the blockchain data inside the internal DB, and read mostly from the internal DB instead of the blockchain.