const AntChain = require('./jssdk.js') const AntCloudClient = require('./base.js') const contractMap = require('./contractMap.json') const b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const b64pad = "="; const BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; function int2char(n) { return BI_RM.charAt(n); } // convert a base64 string to hex function b64tohex(s) { let ret = "" let i; let k = 0; // b64 state, 0-3 let slop; let v; for(i = 0; i < s.length; ++i) { if(s.charAt(i) == b64pad) break; v = b64map.indexOf(s.charAt(i)); if(v < 0) continue; if(k == 0) { ret += int2char(v >> 2); slop = v & 3; k = 1; } else if(k == 1) { ret += int2char((slop << 2) | (v >> 4)); slop = v & 0xf; k = 2; } else if(k == 2) { ret += int2char(slop); ret += int2char(v >> 2); slop = v & 3; k = 3; } else { ret += int2char((slop << 2) | (v >> 4)); ret += int2char(v & 0xf); k = 0; } } if(k == 1) ret += int2char(slop << 2); return ret; } // 初始化客户端 const client = new AntCloudClient({ endpoint: 'https://prodapigw.cloud.alipay.com/gateway.do', accessKey: '${accessKey}', accessSecret: '${accessSecret}', httpclient: { request(endpoint, opt) { return new Promise((resolve, reject) => { my.request({ url: endpoint, headers: { 'Content-Type': opt.contentType || 'application/x-www-form-urlencoded', }, data: opt.data || {}, dataType: 'text', method: opt.method || 'POST', timeout: 10000, success(data) { if (data.status === 200 && data.data) { resolve({ data: data.data }) } else { reject(data) } }, fail(err) { reject(err) } }) }) } } }) const requestParam = { version: '1.0', } let userId = '' function request(data) { const method = data.method || '' const bizid = data.bizid || '' const param = data.param || {} const userP = new Promise((resolve, reject) => { if (userId) { resolve(userId) return } my.getPhoneNumber({ success: (data) => { if (data && data.response) { let response = {} try { response = JSON.parse(data.response) } catch(err) { response = {} console.log(data.response) console.err(err) } if (typeof response.response === 'string') { userId = AntChain.utils.getHash(response.response) resolve(userId) } else { reject(data) } } else { reject(data) } }, fail: (err) => { reject(err) }, }) }) const baasAccountId = 'baas-account-prod' const baasContractId = 'contract-dev-prod' if (method === 'create') { return userP.then(() => { return client.execute({ account: { bizid: bizid, entity_info_type: '0', entity_info_value: userId, full_name: userId, status: '1', target_name: userId, type: '0', uid: userId, }, method: 'baas.account.mapping.start', product_instance_id: baasAccountId, region_name: 'CN-HANGZHOU-FINANCE', ...requestParam }) }) } // 验证用户是否有账户映射 return userP.then(() => { return client.execute({ bizid: bizid, uid: userId, method: 'baas.account.mapping.query', product_instance_id: baasAccountId, region_name: 'CN-HANGZHOU-FINANCE', ...requestParam }).then((resp) => { if (resp.result_code === 'ACCOUNT_NOT_MAPPING' || (resp.result_code === 'OK' && resp.data && resp.data.binding_status !== 2)) { // 给用户创建账户映射 return client.execute({ account: { bizid: bizid, entity_info_type: '0', entity_info_value: userId, full_name: userId, status: '1', target_name: userId, type: '0', uid: userId, }, method: 'baas.account.mapping.start', product_instance_id: baasAccountId, region_name: 'CN-HANGZHOU-FINANCE', ...requestParam }) } return resp }).then(() => { const sdkData = param.data || {params: {transaction: null}} const transaction = sdkData.params.transaction let P = null if (param.isSign && transaction) { // 通过账户映射签名 P = client.execute({ bizid: bizid, uid: userId, algorithm: 'ecdsa', data: transaction.hash || '', method: 'baas.account.signature.start', product_instance_id: baasAccountId, region_name: 'CN-HANGZHOU-FINANCE', ...requestParam }).then((resp) => { if (resp.result_code === 'OK') { transaction.signature = [b64tohex(resp.signature)] sdkData.params.transaction = transaction } return sdkData }) } else { P = new Promise((resolve) => { resolve(sdkData) }) } return P }).then((sdkData) => { // 调用合约代理接口 return client.execute({ bizid: bizid, body: JSON.stringify(sdkData), method: 'baas.contract.delegate.exec', product_instance_id: baasContractId, // region_name: 'CN-HANGZHOU-FINANCE', ...requestParam }) }).then((resp) => { return resp }) }) } const senderData = new AntChain.SenderData({ clientSender(XMLHttpRequest, payload, callback, extend) { const bizid = extend.bizid || '' request({ bizid, param: { isSign: true, data: payload } }).then((data) => { callback(null, data.result) }).catch((err) => { callback(err) }) } }) const antChain = AntChain({ isSign: false, host: 'http://127.0.0.1', port: '80', timeout: 30000, senderData, userPublicKey: '', userPrivateKey: '', userRecoverPublicKey: '', userRecoverPrivateKey: '', passphrase: '', senderData: senderData }) const contractObjMap = {} for (const contractName in contractMap) { const item = contractMap[contractName] contractObjMap[contractName] = antChain.ctr.contract(contractName, item.abi) } const util = { callContract(contractName, method, params) { const contract = contractObjMap[contractName] const contractData = contractMap[contractName] if (contract && contractData && typeof contract[method] === 'function') { const abi = contractData.abi const bizid = contractData.bizid params = Array.isArray(params) ? params : [] return request({ method: 'create', bizid }).then((data) => { return new Promise((resolve, reject) => { if (data && data.data && data.data.baccount) { const account = data.data.baccount params = params.concat([ { from: account, extend: { bizid, follow: { bizid } } }, (err, output, data) => { if (err) { reject(err) return } resolve({ output, data }) } ]) contract[method].apply(contract, params) } else { reject(new Error(data.result_msg || '账户异常')) } }) }) } else { return new Promise((resolve, reject) => { reject(new Error('合约未发布或接口不存在')) }) } } } export default util