opeft-cliet需要谷歌浏览器或Chromium内核
前期准备注册百度账号以及获取私钥充值百度开放网络Tip:用户地址下需要有百度开放网络余额才能使用转移资产,查询余额等功能。建议在百度开放网络充值0.1元。充值链接:https://xuper.baidu.com//cosole#/fiace/wallet/recharge插件使用使用帮助二维码插件安装插件已放置根目录下()国内加速下载 https://gitee.com/shegjia-tech/opeft-cliet/raw/master/MakerONE.zip1,浏览器选择管理扩展程序2,首先打开开发者模式,然后解压下载的压缩包并选择加载,此时您可以看到浏览器已经安装好该插件了3,您可以选择插件常驻插件登录下载私钥到本地之后,打开浏览器插件进入登录页,选择本地私钥,输入安全码登录:用户首页登录之后跳转到首页,显示目前处于百度开放网络,用户百度开放网络地址,余额。以及功能等。查询资产余额:转移资产:查询交易:整体设计:登录页本地私钥路径:需要用户选择本地私钥存放路径,读取私钥内容。安全码(可选)(6位数):根据超级链生成账户的方式可选。开放网络必填。js代码:转换开放网络地址为EVM地址的工具类 addressUtils.jsimportbase58from'bs58'import{sha256}from'js-sha256'exportfuctioXchaiAddrToEvm(addr){varresult=''try{//判断是否是合约账号;判断合约账户地址仅支持XC11111111111@xuper,xuper后缀,go-sdk有相同问题。if(determieCotractAccout(addr)){result=cotractAccoutToEVMAddress(addr)}elseif(determieCotractName(addr)){result=cotractNameToEVMAddress(addr)}else{result=xchaiAKToEVMAddress(addr)}returresult}catch(err){cosole.log(err)}}//判断合约账户地址仅支持XC11111111111@xuper,xuper后缀,go-sdk有相同问题。fuctiodetermieCotractAccout(xchaiAddr){if(isAccout(xchaiAddr)!=1){returfalse}returxchaiAddr.idexOf('@xuper')!=-1}costaccoutPrefix='XC'fuctioisAccout(ame){if(ame==''){retur-1}if(ame.idexOf(accoutPrefix)!=0){retur0}varprefix=ame.split('@')[0]prefix=prefix.substr(accoutPrefix.legth)if(!validRawAccout(prefix)){retur0}retur1}costaccoutSize=16fuctiovalidRawAccout(accoutName){if(accoutName==''){returfalse}if(accoutName.legth!=accoutSize){returfalse}for(vari=0;i<accoutSize;i++){if(accoutName[i]>='0'&&accoutName[i]<='9'){cotiue}else{returfalse}}returtrue}costcotractAccoutPrefixs='1112'costWord160Legth=20fuctiocotractAccoutToEVMAddress(cotractAccout){varcotractAccoutValid=cotractAccout.slice(2,18)varstr=cotractAccoutPrefixs.cocat(cotractAccoutValid)if(str.legth!=Word160Legth){throwewError('slicepassedasaddressshouhave20bytelegth')}returBuffer.from(str).toStrig('hex').toUpperCase()}costcotractNameMaxSize=16costcotractNameMiSize=4costcotractNameRegex=/^[a-zA-Z_]{1}[0-9a-zA-Z_.]+[0-9a-zA-Z_]$/fuctiodetermieCotractName(xchaiAddr){varcotractSize=xchaiAddr.legthif(cotractSize>cotractNameMaxSize||cotractSize<cotractNameMiSize){returfalse}if(!cotractNameRegex.test(xchaiAddr)){returfalse}returtrue}costevmAddressFiller='-'costcotractNamePrefixs='1111'fuctiocotractNameToEVMAddress(cotractName){varcotractNameLegth=cotractName.legthvarprefixStr=''for(vari=0;i<Word160Legth-cotractNameLegth-4;i++){prefixStr+=evmAddressFiller}cotractName=prefixStr+cotractNamecotractName=cotractNamePrefixs+cotractNameif(cotractName.legth!=Word160Legth){throwewError('slicepassedasaddressshouhave20bytelegth')}returBuffer.from(cotractName).toStrig('hex').toUpperCase()}fuctioxchaiAKToEVMAddress(xchaiAddr){varrawAddr=base58.decode(xchaiAddr)if(rawAddr.legth<21){throwewError('badaddress')}rawAddr=rawAddr.slice(1,21)returBuffer.from(rawAddr,'').toStrig('hex').toUpperCase()}exportfuctioEvmToXchaiAddr(addr){//returaddr,addrType,ilvarresult=''try{varbs=Buffer.from(addr,'hex').toStrig('ascii')if(bs.legth!=Word160Legth){throwewError('slicepassedasaddressshouhave20bytelegth')}varevmAddrStrWithPrefix=bs//合约账号if(evmAddrStrWithPrefix.slice(0,4)==cotractAccoutPrefixs){result=evmAddressToCotractAccout(bs)}elseif(evmAddrStrWithPrefix.slice(0,4)==cotractNamePrefixs){result=evmAddressToCotractName(bs)}else{varbuffer=Buffer.from(addr,'hex')result=evmAddressToXchai(buffer)}returresult}catch(err){cosole.log(err)}}fuctioevmAddressToCotractAccout(addr){returaccoutPrefix+addr.slice(4)+'@xuper'}fuctioevmAddressToCotractName(addr){varidex=addr.lastIdexOf(evmAddressFiller)returaddr.slice(idex+1)}fuctioevmAddressToXchai(addr){varaddTyepe=[]varaddrArray=ewUit8Array(addr)addTyepe.push(1)for(vari=0;i<addrArray.legth;i++){addTyepe.push(addrArray[i])}varcheckCode=DoubleSha256(addTyepe)varsimpleCheckCode=checkCode.slice(0,4)for(vari=0;i<simpleCheckCode.legth;i++){addTyepe.push(simpleCheckCode[i])}returbase58.ecode(addTyepe)}//DoubleSha256执行2次SHA256,这是为了防止SHA256算法被攻破。fuctioDoubleSha256(data){returUsigSha256(UsigSha256(data))}//UsigSha256getthehashresultofdatausigSHA256fuctioUsigSha256(data){retursha256.array(data)} //需要引入XuperSDK和上面的地址转换工具类importXuperSDK,{Edorsemet}from'@xuperchai/xuper-sdk'import{XchaiAddrToEvm}from'./addressUtils'//TODO需要通过用户选择的私钥路径,读取出来私钥的内容costprivate=''//安全码costpassword=''//登录后生成账户对象costacc=xsdk.import(password,private) 首页默认首页用户处于开放网络。开放网络为下拉框,默认一个位开放网络。用户可以添加网络。添加网络可以弹框,需要参数:网络名(用户自己输入就行),节点IP(例如:39.156.69.83:37100),链名:(例如xuperchai), Vue里面开放网络的ode需要设置为https://xuper.baidu.com/odeapi//默认就有的开放网络,默认开放网络的链名costode='39.156.69.83:37100'//vue里面设置为https://xuper.baidu.com/odeapicostchai='xuper'//连接开放网络时需要加载背书服务,costparams={server:'39.156.69.83:37100',//ip,port//vue里面设置为https://xuper.baidu.com/odeapifee:'400',//feeedorseServiceCheckAddr:'jkGxa6eyum1JrATWvSJKW3thJ9GKHA9',//sigaddressedorseServiceFeeAddr:'aB2hpHTBDxko3UoP2BpBZRujwhdcAFoT',//feeaddress}//默认的开放网络SDKcliet,后续查询余额,调用合约使用。costxsdk=ewXuperSDK({ode,chai,plugis:[Edorsemet({trasfer:params,makeTrasactio:params,}),],})//用户新增网络可以生成新的sdkcliet并记录,切换网络即切换SDK,新增网络暂时不考虑背书插件,仅传入IP和链名即可costxsdk=ewXuperSDK({ode,chai,}) 显示用户Address//用户登录时生成的acc,acc.address即为用的address地址costaddr=acc.address 显示用户余额//查询登录用户余额//用户超级链账户余额address直接传入上面acc.address即可。costbalace=asyc(adress)=>{try{costresult=awaitxsdk.getBalace(adress)debug(result.bcs[0].balace)}catch(err){throwerr}} 默认提供三个Actio功能,转移NFT。查询NFT数量,查询交易。并提供新增Actio操作点击功能,跳转到功能页。最上面为下拉框,用户可以选择功能,默认为上述三个,并且有一个新增操作。默认三个功能转移,查询,查询交易//默认合约名costcotractName='opeft'//默认方法名costmethodName='safeTrasferFrom'//默认参数//ft转移发起者,默认取值acc.address,acc.address需要转换,下述为转换好的。//acc.address格式为ULuqhymLPGidfihUb683i2TH4qtaqZ2Dz需要用工具类转换为evm的地址2BEF68690AE24553824BA37C003C2B9067665F81costfrom=XchaiAddrToEvm(acc.address)//下述三个参数,需要用户在页面输入,提供三个输入框即可。//ft转移接受者前端输入例如cRsoDDDX1NjhzJtNKLS3GHudBsgyRouQ也需要转换costto=XchaiAddrToEvm('cRsoDDDX1NjhzJtNKLS3GHudBsgyRouQ')//转移的fttokeidcostftTokeID='6'//转移数量costamout='1'//转移NFT转移操作前先查询一下账户余额。是0的话让他去充值。建议最少充值一元。//咱们默认提供的NFT转移,只需要转移着的地址,tokeid,数量。给用户返回交易IDcostTrasferNFTEvm=asyc(toAddr,TokeID,Amout)=>{try{costcotractName=cotractNamecostmethodName=methodNamecostdemo=awaitxsdk.ivokeSolidityCotarct(cotractName,methodName,'evm',{from:from,to:to,id:ftTokeID,amout:amout,data:'',},'0',acc)//352cd3f829dded7ad1da7ab3a0c3a8776cd3ec545c617ad499abb2d29459c6ee//交易ID返回给用户debug(xsdk.trasactioIdToHex(demo.trasactio.txid))costresult=awaitxsdk.postTrasactio(demo.trasactio,acc)//TODO调用转移操作成功后//TODO调用坤那边的服务端接口解析交易只传输txid,调用接口即可,后续不管。最后给用户返回上面的交易ID就行。debug(result)//err是空证明转移成功,不是就是执行失败。}catch(err){cosole.log(err)}} 查询自己的NFT余额//查询NFT余额前端用户选择查询资产余额,需要输入NFTtokeID就行,然后返回余额数量就OK。costqueryNFTBalace=asyc(tokeID)=>{try{costcotractName='opeft'costmethodName='balaceOf'costargs={accout:XchaiAddrToEvm(acc.address),id:tokeID,}costdemo=awaitxsdk.ivokeSolidityCotarct(cotractName,methodName,'evm',args,'0',acc)//判断demo.preExecutioTrasactio.respose.resposes的长度是否大于0,大于0取demo.preExecutioTrasactio.respose.resposes[legth-1]costle=demo.preExecutioTrasactio.respose.resposes.legthif(le>0){coststr=demo.preExecutioTrasactio.respose.resposes[le-1].bodycostresult=Buffer.from(str,'base64').toStrig('ascii')//[{\"0\":\"10\"}]result即为[{\"0\":\"10\"}]10即为想要的结果,即对应ft的余额debug(result)}}catch(err){cosole.log(err)}} 查询交易信息//查询交易前端用户选择查询交易,让用户输入交易ID,即可,返回交易信息。目前交易信息很少//查询交易costGetTxDetail=asyc(txID)=>{try{costdemo=awaitxsdk.queryTrasactio(Buffer.from(txID,'hex').toStrig('base64'))if(demo.tx==udefied){//证明此交易链上没有直接报错throwewError('thistxudefied')}//交易IDvartxID=Buffer.from(demo.tx.txid,'base64').toStrig('hex')vartxReqJso=JSON.parse(Buffer.from(demo.tx.cotract_requests[1].args.iput,'base64').toStrig())varfrom=''varto=''vartokeID=''varamout=''if(demo.tx.cotract_requests[1].method_ame=='safeTrasferFrom'){from=EvmToXchaiAddr(txReqJso.from)to=EvmToXchaiAddr(txReqJso.to)tokeID=txReqJso.idamout=txReqJso.amout}else{from=demo.tx.iitiatortokeID=txReqJso._idamout=txReqJso._iitialSupply}//根据tokeID查询tokeid的图片路径供浏览器跳转costcotractName='opeft'costmethodName='getTokeBytes'costargs={_id:tokeID,}costres=awaitxsdk.ivokeSolidityCotarct(cotractName,methodName,'evm',args,'0',acc)costle=res.preExecutioTrasactio.respose.resposes.legthif(le>0){varresult=res.preExecutioTrasactio.respose.resposes[le-1].bodyvarrespose=JSON.parse(Buffer.from(result,'base64').toStrig())varbase64Addr=respose[0]._resposevardata=Buffer.from(base64Addr,'base64').toStrig()vardataJso=JSON.parse(data)}vartimestamp=parseIt(demo.tx.timestamp/1000)//用户查看交易详情,前端显示下述txDetail信息。vartxDetail={txID:txID,from:from,to:to,id:tokeID,amout:amout,timestamp:timestamp,}varftDetail={lik:dataJso.lik,ame:dataJso.ame,hash:dataJso.hash,}//前端展示数据cosole.log(txDetail)cosole.log(ftDetail)returtxDetail,ftDetail}catch(err){cosole.log(err)}} 用户新增actio操作。不用再首页展示,只在第三张图的下拉框显示即可。用户新增功能需要传入参数较多(TODO)//下述,所有参数可设置默认值。用户新增功能时,用户可以设置是否用户输入。,前端不显示,不设置即前端需要输入。//需要传入参数costcotractName='合约名'costmethod='方法名'//调用方法的参数。(前端可选多个)costfrom='';costto='';... 切换账号功能用户点击头像,可以新增账户,即新增一个acc对象,切换账户,即切换acc对象。新增账户也需要指定私钥,安全码(非必须)。(TODO)//TODO需要通过用户选择的私钥路径,读取出来私钥的内容costprivate=''//安全码costpassword=''//登录后生成账户对象costacc=xsdk.import(password,private)
评论