Skip to content

About

Uptick CosWasm 极简商城合约与店铺式 Keplr dApp 前端

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

wasm-mall — 最简单的 Uptick Chain 商城合约

一个跑在 Uptick Chain CosWasm VM 上的极简商城合约(Rust + CosmWasm 1.5),内置资金托管(escrow)与退款闭环。

功能

  • 上架商品 ListProduct { name, price, stock } —— 调用者自动成为卖家,合约分配自增 id
  • 购买 BuyProduct { product_id, quantity } —— 必须随交易附上精确的 price × quantity 原生币;合约先把钱托管在合约里(不下发给卖家),并生成一笔 Order{status: created},同时扣减库存
  • 确认收货 ConfirmReceipt { order_id } —— 仅买家可调用,把托管款打给卖家,订单置 completed
  • 申请退款 RequestRefund { order_id } —— 仅买家可调用,把托管款退回买家,并恢复库存,订单置 refunded
  • 查询 Config / Product{id} / Products{分页} / ProductsBySeller{seller} / Order{id} / OrdersByBuyer{buyer}

资金闭环(escrow)

买家 BuyProduct ──付款──▶ 合约托管 (Order.created, 库存-)
        │
        ├─▶ 买家 ConfirmReceipt ──▶ 放款给卖家 (Order.completed)
        └─▶ 买家 RequestRefund ──▶ 退款给买家 + 库存恢复 (Order.refunded)

解决了“先钱后货”的信任问题:卖家不发货,买家退款即可拿回本金;买家确认收货,卖家才能拿到钱。

说明:为求最小,仍没有管理员改价/下架、没有纠纷仲裁、没有平台抽成。这些见文末「可扩展点」。

目录

wasm-store/
├── README.md            # 本文件:总览 + 构建 / 部署 / 前端说明
├── Makefile             # make test / build / deploy 标准工作流
├── Cargo.toml           # CosmWasm 合约(crate: wasm-mall,惯例放在仓库根)
├── .gitignore
├── src/                 # 合约源码
│   ├── lib.rs           # 模块声明
│   ├── state.rs         # Config / Product / Order 数据结构 + 存储键
│   ├── msg.rs           # Instantiate / Execute / Query 消息与响应
│   ├── error.rs         # ContractError
│   ├── contract.rs      # instantiate / execute / query 实现
│   └── tests.rs         # cw-multi-test 单元测试(含托管 / 退款 / 越权用例)
├── scripts/             # 部署与交互脚本
│   ├── deploy.sh        # uptickd CLI 一键 store + instantiate
│   ├── mall-client.mjs  # CosmJS node 交互脚本
│   └── package.json     # CosmJS 依赖(npm install 在此目录)
├── frontend/            # 店铺式 Keplr dApp(纯静态单文件)
│   └── index.html
├── docs/                # 文档
│   ├── WORK_LOG.md      # 工作日志(chronological)
│   └── HANDOVER.md      # 交接文档(给下一开发者)
└── artifacts/           # (gitignored) make build 产物 wasm_mall.wasm

合约按 CosmWasm 惯例放在仓库根(Cargo.toml 在根),而不是 contracts/ 子目录——这样 make build / deploy.sh 的相对路径最简单。前端与脚本各自成目录。

更完整的架构说明、构建 / 部署 / 前端运行步骤、网络参数、关键坑与验收清单,见 docs/HANDOVER.md;开发历程见 docs/WORK_LOG.md。

本地构建(你在终端跑,沙箱不联网)

1. 装 Rust + wasm 目标

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown

2. 跑单元测试

cargo test

3. 用官方 optimizer 编译出 wasm(推荐,体积最小、可复现)

docker run --rm \
  -v "$(pwd)":/code \
  --mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
  --name cosmwasm-optimizer cosmwasm/optimizer:0.16.0

产物:artifacts/wasm_mall.wasm

CosmWasm 2.x 链可改用 cosmwasm/optimizer:0.17 并把 Cargo.toml 里 cosmwasm-std 升到 2.0。Uptick 当前 1.x 运行时用 0.16.0 即可。 注意:缓存卷不要加 readonly —— optimizer 需要往 /target 写编译缓存,readonly 会让构建直接失败。

也可以用 Makefile 一键跑:make test / make build / make deploy(deploy 依赖 KEY / CHAIN_ID / DENOM / NODE 环境变量)。

若节点拒绝 --gas-prices 0auoc,把 gas price 调成最小值即可(例如 --gas-prices 0.025auoc)。Uptick 官方示例多用 0,照抄通常能通过。

部署到 Uptick Chain

链参数速查

网络 chain-id 原生 base denom RPC
主网 uptick_117-1 auptick (你的节点 / 公共 RPC)
Origin 测试网 origin_1170-3 auoc(显示 UOC) https://rpc.origin.uptick.network

下面以 Origin 测试网 为例,主网把 chain-id / denom / RPC 替换即可。

0. 前置准备(仅首次)

  1. 装 uptickd(版本必须与目标网络一致):测试网 origin_1170-3 当前为 v0.2.x 系,主网 uptick_117-1 为 v0.3.3 / 升级目标 v0.5.0。从源码装最稳:
    git clone https://github.com/UptickNetwork/uptick.git
    cd uptick && git checkout <对应tag> && make install
    uptickd version
    详见官方文档(upticknft.gitbook.io / docs.uptick.network 的 Installation / Joining a Testnet)。
  2. 建/导入钱包:uptickd keys add mykey --keyring-backend test(或 --recover 导入已有助记词),记下地址。
  3. 领测试币 auoc:进 Uptick Discord #faucet 频道 发 $faucet <你的地址>,或用 Keplr 水龙头 点 Request Funds。主网需真实 auptick。
  4. 确认余额:uptickd query bank balances <地址> --node https://rpc.origin.uptick.network。

不需要在你 EC2 跑全节点——“上链”只是把交易通过公开 RPC 广播到 Uptick 网络;deploy.sh 默认就连 https://rpc.origin.uptick.network。

方式 A:一键部署(推荐)

KEY=mykey ./deploy.sh
# 脚本会 store + instantiate,并输出:
#   export CODE_ID=...
#   export CONTRACT=...
# 复制这两行到 shell 即可供 mall-client.mjs / 后续命令使用。

所有变量都可前置覆盖:CHAIN_ID=uptick_117-1 DENOM=auptick NODE=https://... KEY=mykey KEYRING=test ./deploy.sh

方式 B:手动

export KEY=<你的key名>
export NODE=https://rpc.origin.uptick.network
export CHAIN=origin_1170-3

# 1. 存储代码
uptickd tx wasm store artifacts/wasm_mall.wasm \
  --from $KEY --chain-id $CHAIN --node $NODE --keyring-backend test \
  --gas auto --gas-prices 0auoc -y -b block
uptickd query wasm list-code --node $NODE --output json   # 记下 code_id

# 2. 实例化(指定接受的支付 denom)
uptickd tx wasm instantiate <CODE_ID> '{"denom":"auoc"}' \
  --from $KEY --label "wasm-mall" --chain-id $CHAIN --node $NODE --keyring-backend test \
  --gas auto --gas-prices 0auoc -y -b block --no-admin

上架 / 购买 / 确认 / 退款(CLI)

# 上架(卖家)
uptickd tx wasm execute <CONTRACT_ADDR> \
  '{"list_product":{"name":"Uptick T-Shirt","price":"1000000000000000000","stock":10}}' \
  --from $SELLER --chain-id $CHAIN --node $NODE \
  --gas auto --gas-prices 0auoc -y -b block
# price 是 base 单位:auptick/auoc 都是 18 位小数,1 = 1000000000000000000

# 购买(买家,必须带精确金额;返回事件里含 order_id)
uptickd tx wasm execute <CONTRACT_ADDR> \
  '{"buy_product":{"product_id":1,"quantity":1}}' \
  --from $BUYER --chain-id $CHAIN --node $NODE \
  --amount 1000000000000000000auoc \
  --gas auto --gas-prices 0auoc -y -b block

# 确认收货 → 放款给卖家(买家)
uptickd tx wasm execute <CONTRACT_ADDR> \
  '{"confirm_receipt":{"order_id":1}}' \
  --from $BUYER --chain-id $CHAIN --node $NODE \
  --gas auto --gas-prices 0auoc -y -b block

# 申请退款 → 退款给买家并恢复库存(买家)
uptickd tx wasm execute <CONTRACT_ADDR> \
  '{"request_refund":{"order_id":1}}' \
  --from $BUYER --chain-id $CHAIN --node $NODE \
  --gas auto --gas-prices 0auoc -y -b block

查询

uptickd query wasm contract-state smart <CONTRACT_ADDR> '{"product":{"id":1}}' --node $NODE
uptickd query wasm contract-state smart <CONTRACT_ADDR> '{"products":{"limit":10}}' --node $NODE
uptickd query wasm contract-state smart <CONTRACT_ADDR> '{"products_by_seller":{"seller":"uptick1xxxx","limit":10}}' --node $NODE
uptickd query wasm contract-state smart <CONTRACT_ADDR> '{"order":{"id":1}}' --node $NODE
uptickd query wasm contract-state smart <CONTRACT_ADDR> '{"orders_by_buyer":{"buyer":"uptick1yyyy","limit":10}}' --node $NODE

CosmJS 交互脚本

scripts/mall-client.mjs 用 @cosmjs/cosmwasm-stargate 封装了全部读写操作,并带 CLI。

cd scripts                       # 依赖声明在 scripts/package.json
npm install                      # 安装 CosmJS 依赖
export MNEMONIC="你的助记词"
export CONTRACT=<实例化得到的合约地址>   # 或 CODE_ID 用于 instantiate

node mall-client.mjs instantiate <CODE_ID>          # 部署实例,输出合约地址
node mall-client.mjs list "T-Shirt" 1000000000000000000 10
node mall-client.mjs buy 1 1 1000000000000000000    # 自动带 --amount
node mall-client.mjs confirm 1
node mall-client.mjs refund 1
node mall-client.mjs product 1
node mall-client.mjs orders uptick1yyyy

环境变量:RPC / CHAIN_ID / DENOM / PREFIX / MNEMONIC / CONTRACT / CODE_ID 均可覆盖。 前端 / Keplr 集成:把 makeClient() 里的 DirectSecp256k1HdWallet.fromMnemonic(...) 换成 const signer = await window.keplr.getOfflineSignerOnlyAmino(CHAIN_ID);,其余 execute/query 调用完全一致。

浏览器前端(Keplr dApp · 店铺 UI)

frontend/index.html 是一个纯静态、无后端的店铺式 Web 前端,让你在浏览器里用 Keplr 钱包直接签名、调用链上合约——和 EVM + MetaMask 的前端是同一个套路。合约部署在链上(见上方「部署到 Uptick Chain」),前端只负责签名与广播,可托管在任意静态空间(test01 的 nginx / GitHub Pages / 本地直接打开)。

界面构成(已重做为真正店铺,非调试面板)

  • 顶栏:品牌 Logo + 网络切换(测试网/主网)+ 连接钱包(连接后显示地址与余额)。
  • Hero 横幅:链上商城卖点。
  • 商品网格:卡片含缩略图、名称、价格、库存徽章(有货/仅剩 N/售罄)、卖家、购买按钮。
  • 购买弹窗:数量步进器 + 自动计算应付总额(托管)。
  • 上架弹窗(+ 上架商品):卖家发布商品,价格按显示单位填写(如 12.5 UOC),前端自动转成最小单位整数发给合约。
  • 我的订单抽屉:买家订单列表,状态标签 + 确认收货(放款)/ 申请退款(退钱+补库存)按钮。
  • 开发者设置(底部折叠):合约地址填写、部署 wasm、查配置、调试日志——把原来的调试面板收起,不干扰购物体验。

工作流程

  1. 浏览器打开 frontend/index.html(本地双击或静态托管均可)。
  2. 点「连接 Keplr 钱包」——首次会先把 Uptick 网络加入 Keplr(自动 experimentalSuggestChain)。
  3. 部署(可选):在「开发者设置」选本地 artifacts/wasm_mall.wasm → 点「上传 + 实例化」,Keplr 弹窗签名两笔交易(store + instantiate),合约地址自动填入;也可直接用上方 deploy.sh 部署后再把地址粘贴进来。
  4. 购物:点商品「购买」→ 选数量 → 确认(托管付款);卖家点「+ 上架商品」发布;买家在「我的订单」里确认/退款。

要点

  • 价格输入框已改为显示单位(UOC / uptick),前端用 parseDisplayToMin 精确转最小单位整数(避免浮点误差),合约仍按 base 单位存储。
  • 主网部署请把「开发者设置」里 Gas Price 改为实值(如 0.002auptick)并切换网络;小数位若与主网不一致,改 CHAINS 里的 decimals。
  • 依赖经 esm.sh CDN 加载 @cosmjs/cosmwasm-stargate,无需 npm install;需浏览器支持 ES Modules + 已装 Keplr 扩展。
  • Keplr 仅在 https / localhost / file:// 安全上下文响应——本地可用 python3 -m http.server 起静态服务,或部署到 test01 的 nginx。

可扩展点(按需再加)

  • 纠纷仲裁:引入仲裁员/管理员,在 created 状态下可强制放款或退款。
  • 管理员改价 / 下架:用 Config.admin 做权限校验。
  • 多卖家目录索引:用 (Addr, u64) -> u64 的 Map 给卖家建索引,避免全表扫描。
  • 平台手续费抽成:ConfirmReceipt 放款时把一部分打给平台地址。
  • 自动确认/退款超时:结合 created_height 设超时,到期自动 confirm 或 refund。
  • NFT 商品:结合 Uptick 的 CW721,购买即转移 NFT。

Uptick Chain · CosWasm VM · CosmWasm 1.5

About

Uptick CosWasm 极简商城合约与店铺式 Keplr dApp 前端

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages