go-ethereum mint nft用户支付实现

发布时间 2023-10-02 21:58:59作者: 若-飞

代码:

package main

// 签名用的公钥私钥也是采用的owner的公钥私钥

import (
	"context"
	"fmt"
	"math/big"

	"user-pay/triplec"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/common/hexutil"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
)

const (
	BETA_SERVER_ADDRESS             = "https://data-seed-prebsc-1-s1.bnbchain.org:8545"
	BETA_CONTRACT_ADDRESS           = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
	BETA_CONTRACT_OWNER_PUBLIC_KEY  = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
	BETA_CONTRACT_OWNER_PRIVATE_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
)

func GetConfig() (string, string, string, string) {
	// 默认返回 beta 配置
	return BETA_SERVER_ADDRESS, BETA_CONTRACT_ADDRESS, BETA_CONTRACT_OWNER_PUBLIC_KEY, BETA_CONTRACT_OWNER_PRIVATE_KEY
}

func main() {
	serverAddress, contractAddress, ownerPublicKey, ownerPrivateKey := GetConfig()
	fmt.Printf("serverAddress:%v, contractAddress:%v, ownerPublicKey:%v, ownerPrivateKey:%v", serverAddress, contractAddress, ownerPublicKey, ownerPrivateKey)

	var (
		pId            = int64(1)                                                           // 勋章ID
		dummyId        = int64(1)                                                           // 全局唯一ID,可以是表的ID,自己生成也行,仅用来进行防止重复mint
		level          = int64(0)                                                           // 勋章等级
		userPublicKey  = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"                          // 用户公钥
		userPrivateKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"                          // 用户私钥
		canTransfer    = false                                                              // 勋章是否支持转账
	)

	// 连接到节点
	client, _ := ethclient.Dial(serverAddress)
	chainId, err := client.ChainID(context.Background())
	if err != nil {
		panic(err)
	}

	// 服务器签名:使用合约管理员的私钥
	sign, err := MedalNftSigner(ownerPrivateKey, chainId.Int64(), contractAddress, pId, dummyId, level, userPublicKey, canTransfer)
	if err != nil {
		panic(err)
	}
	fmt.Printf("sign:%v\n", sign)

	// 用户信息
	userPrivateKeyEcdsa, err := crypto.HexToECDSA(userPrivateKey)
	if err != nil {
		panic(err)
	}
	auth, err := Author(userPrivateKeyEcdsa, client, 500000, 0)
	if err != nil {
		panic(err)
	}

	medal, err := triplec.NewTriplec(common.HexToAddress(contractAddress), client)
	if err != nil {
		panic(err)
	}

	// 客户端调用claim,验证签名:签名
	{
		signBytes, err := hexutil.Decode(sign)
		if err != nil {
			panic(err)
		}

		tx, err := medal.Claim(auth, big.NewInt(pId), big.NewInt(dummyId), big.NewInt(level), common.HexToAddress(userPublicKey), canTransfer, signBytes)
		if err != nil {
			panic(err)
		}
		hash := tx.Hash().Hex()
		fmt.Printf("hash:%s \n", hash)
	}

}

流程是:

0. 需要全局设置一个signer,用于验证签名的:参考上一篇文章:https://www.cnblogs.com/zhanchenjin/p/17740483.html

1. 服务器签名:使用合约管理员的私钥对一笔交易进行签名

2. 客户端使用签名发起claim交易: