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

React应用中调用Functions.makeHTTPrequest及fetch API,传入executeRequest合约

1. 将React组件转为字符串并调用Functions.makeHTTPRequest

步骤拆解

  • 组件转字符串:使用ReactDOMServer的renderToStaticMarkup(生成纯静态HTML)或renderToString(带React内部标识),把组件转为字符串格式
  • 构造Chainlink HTTP请求:按照Chainlink Functions规范,用Functions.makeHTTPRequest封装请求参数,将组件字符串作为请求体或参数传入
  • 调用合约executeRequest:通过ethers.js/wagmi连接合约,将编码后的请求数据和组件字符串传入合约函数

代码示例

import ReactDOMServer from 'react-dom/server';
import { Functions } from '@chainlink/functions-toolkit';
import { ethers } from 'ethers';
import FunctionConsumerABI from './FunctionConsumerABI.json';

// 目标React组件
const MyComponent = () => (
  <div>
    <h1>Chainlink Functions Demo</h1>
    <p>生成时间: {new Date().toLocaleString()}</p>
  </div>
);

const executeChainlinkRequest = async () => {
  // 1. 组件转HTML字符串
  const componentString = ReactDOMServer.renderToStaticMarkup(<MyComponent />);

  // 2. 构造Chainlink HTTP请求
  const httpRequest = Functions.makeHTTPRequest({
    url: 'https://your-api-endpoint.com',
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ component: componentString })
  });

  // 3. 编码Chainlink请求数据
  const requestData = Functions.encodeRequestData(
    [httpRequest],
    [], // 无需加密密钥则传空数组
    100000 // 回调函数gas限制
  );

  // 4. 调用智能合约executeRequest
  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();
  const contract = new ethers.Contract('0xYourContractAddress', FunctionConsumerABI, signer);

  const tx = await contract.executeRequest(requestData, componentString);
  await tx.wait();
  console.log('交易已上链:', tx.hash);
};

2. React中发起POST请求并传入字符串到executeRequest

如果不需要通过Chainlink Functions转发HTTP请求,直接在React中发起POST请求后将结果/组件字符串传入合约:

代码示例

import ReactDOMServer from 'react-dom/server';
import { ethers } from 'ethers';
import FunctionConsumerABI from './FunctionConsumerABI.json';

const MyComponent = () => (
  <div className="custom-component">
    <h2>自定义业务组件</h2>
    <p>待传入合约的内容</p>
  </div>
);

const postAndCallContract = async () => {
  // 组件转字符串
  const componentString = ReactDOMServer.renderToStaticMarkup(<MyComponent />);

  // 发起POST请求
  const postRes = await fetch('https://your-api.com/submit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ componentHtml: componentString })
  });
  const apiResult = await postRes.json();

  // 调用合约executeRequest
  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();
  const contract = new ethers.Contract('0xYourContractAddress', FunctionConsumerABI, signer);

  // 假设合约executeRequest接收两个字符串参数:API返回结果、组件字符串
  const tx = await contract.executeRequest(JSON.stringify(apiResult), componentString);
  await tx.wait();
};

3. 基于fetch API实现完整流程(调用API+传入组件字符串到合约)

结合fetch调用第三方API,将组件字符串传给API处理后,再将结果和组件字符串一并传入合约:

代码示例

import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { ethers } from 'ethers';
import FunctionConsumerABI from './FunctionConsumerABI.json';

// 业务组件
const BusinessComponent = () => (
  <div>
    <h3>用户业务内容</h3>
    <p>ID: {Math.random().toString(36).slice(2, 10)}</p>
  </div>
);

const fullFlowExecute = async () => {
  try {
    // 1. 组件转字符串
    const componentStr = ReactDOMServer.renderToStaticMarkup(<BusinessComponent />);

    // 2. fetch调用API,传入组件字符串
    const fetchRes = await fetch('https://your-service-api.com/process', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        // 如有需要添加API鉴权头
        // 'Authorization': 'Bearer YOUR_API_TOKEN'
      },
      body: JSON.stringify({
        sourceHtml: componentStr,
        timestamp: Date.now()
      })
    });

    if (!fetchRes.ok) throw new Error(`API请求失败: ${fetchRes.status}`);
    const processedData = await fetchRes.json();

    // 3. 调用合约executeRequest
    const provider = new ethers.BrowserProvider(window.ethereum);
    const signer = await provider.getSigner();
    const contract = new ethers.Contract('0xYourContractAddress', FunctionConsumerABI, signer);

    const tx = await contract.executeRequest(
      JSON.stringify(processedData),
      componentStr,
      { gasLimit: 300000 } // 根据实际需求设置gas限额
    );

    await tx.wait();
    console.log('交易确认,哈希:', tx.hash);
  } catch (err) {
    console.error('流程执行出错:', err);
  }
};

// 页面触发按钮
export default function App() {
  return (
    <div style={{ padding: '20px' }}>
      <button onClick={fullFlowExecute} style={{ padding: '10px 20px' }}>
        执行完整流程
      </button>
    </div>
  );
}

关键注意事项

  • 字符串大小限制:Solidity中字符串存储有gas成本,过长的HTML字符串可能导致交易失败,建议用html-minifier等工具压缩后再传入
  • 合约参数匹配:确保FunctionConsumer.sol的executeRequest函数参数类型与传入值一致,例如Solidity中用string类型接收字符串参数
  • Chainlink配置:若使用Chainlink Functions,需提前配置好Functions订阅,确保请求参数符合Chainlink的规范要求

内容的提问来源于stack exchange,提问作者Kenil shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:08:15