You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ClojureScript中Web3 1.5.2部署合约Promise无法resolve问题如何修复

修复方案

核心原因

web3.js 1.5.2版本的contract.deploy().send()方法存在已知行为异常:如果调用send时同时传入回调函数、绑定事件监听并等待Promise返回,会导致Promise无法正常resolve,即使交易已经完成链上确认,这是导致你问题的核心诱因。

修复步骤

  • 移除send方法的回调参数
    你当前代码中给send传入了打印错误和交易哈希的回调,回调和Promise模式混用会触发web3.js的bug,把这部分逻辑迁移到error事件和sending事件中处理即可。
  • 调整确认数配置(可选)
    你配置的transactionConfirmationBlocks: 3需要和部署链的出块规则匹配,测试时可以临时改为1,确认逻辑跑通后再调整为合适的数值。
  • 兜底方案:直接在receipt事件中完成后续逻辑
    如果修改后Promise仍然无法正常resolve,直接在receipt事件回调中通过返回的合约地址手动初始化合约实例,执行后续的dispatch逻辑,不需要等待Promise resolve。

修改后的代码示例

(go (let [web3
          (Web3. (.-givenProvider Web3))

          ego
          (-> (<p! (.. web3 -eth (getAccounts)))
              (nth 0))

          contract
          (new (.. web3 -eth -Contract)
            (.-abi (js/JSON.parse contract-json))
            nil
            (clj->js {:transactionConfirmationBlocks 3}))

          contract-deploy
          (.. contract
              (deploy (clj->js
                        {:arguments [ipfs]
                         :data (.-bytecode (js/JSON.parse contract-json))})))]
        ;;(prn "ego is " ego)
        (let [contract-send
              (.. contract-deploy
                  ;; 移除send的回调参数,避免混用回调和Promise模式
                  (send (clj->js {:from ego})))
             

              contract-instance
              (try
                (<p!
                  (.. contract-send
                      (on "error" (fn [obj] 
                                    (prn "err is " obj)
                                    (js/console.log "error " obj)))
                      (on "sending" (fn [obj] 
                                      (prn "sending " obj)
                                      ;; sending事件的payload中可直接获取tx hash
                                      (prn "tx hash is " (.-hash obj))))
                      (on "receipt" (fn [receipt] 
                                     (prn "contract address is" (.-contractAddress receipt))))
                      (on "confirmation" (fn [confirmation-number receipt]
                                            (dispatch [:stop-loading])    
                                            (prn "confirmation number"
                                                 confirmation-number)
                                            (prn "receipt"
                                                 receipt)))))
                (catch js/Object e
                  (.log js/console "contract error " e)))]
          (when contract-instance
            (dispatch [:issue-nfts contract-instance
                       contract-json ego]))))

兜底方案代码

如果调整后Promise仍然无法resolve,直接在receipt事件中触发后续逻辑即可,完全不需要等待Promise返回:

(on "receipt" (fn [receipt]
               (prn "contract address is" (.-contractAddress receipt))
               ;; 手动初始化合约实例
               (let [contract-instance (new (.. web3 -eth -Contract)
                                            (.-abi (js/JSON.parse contract-json))
                                            (.-contractAddress receipt))]
                 (dispatch [:issue-nfts contract-instance contract-json ego]))))

内容的提问来源于stack exchange,提问作者zendevil.eth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:12:03