すべてのプロダクト
Search
ドキュメントセンター

Blockchain as a Service:コントラクトインターフェイス

最終更新日:Apr 01, 2026

BaaS JS SDK は、スマートコントラクトの作成、デプロイメント、呼び出し、および更新を簡素化する専用のコントラクトインターフェイスを提供します。このインターフェイスを使用する前に、ABI (Application Binary Interface) およびバイトコードについて理解しておいてください。詳細については、「Cloud IDE スマートコントラクト開発環境」をご参照ください。

以下のすべての例では、「Solidity スマートコントラクト開発」で紹介されている CreditManager コントラクトを使用します。JS SDK は Solidity コンパイラである solc-js と連携します。詳細については、「Solidity を使用したコントラクトのコンパイル」をご参照ください。

スマートコントラクトインスタンスの作成

chain.ctr.contract() を呼び出して、スマートコントラクトインスタンスを作成します。コントラクト ID はコントラクト名のハッシュとなるため、各コントラクトには一意の名前を使用してください。

パラメーター

パラメーター必須説明
nameはいstringスマートコントラクトの名前です。コントラクト ID はこの名前のハッシュとなります。
abiはいstringJSON 形式の文字列としての ABI です。
vmTypeいいえstringコントラクト言語です。C++ の場合は chain.WASM を設定します。Solidity の場合はデフォルトで chain.EVM が使用されます。

例 1:Solidity コントラクト

solc-js を使用して Solidity コントラクトをコンパイルし、EVM コントラクトインスタンスを作成します。

const solc = require('@alipay/solc')
const contract = fs.readFileSync('./CreditManager.sol', { encoding: 'ascii' })
// 2 番目のパラメーターを 1 に設定してコンパイルを開始します
const output = solc.compile(contract, 1)
const abi = JSON.parse(output.contracts[':CreditManager'].interface)
const bytecode = output.contracts[':CreditManager'].bytecode

// コントラクト名の ID が一意になるようにタイムスタンプを追加します
const contractName = 'contract' + Date.now()
// スマートコントラクトインスタンスを初期化します
let myContract = chain.ctr.contract(contractName, abi)

例 2:C++ (WebAssembly) コントラクト

ローカルファイルから Wasm バイトコードおよび ABI を読み取り、WASM コントラクトインスタンスを作成します。

const wasm_code = fs.readFileSync('./contract/base.wasm')
const abi = fs.readFileSync('./contract/base.abi')
const bytecode = '0x' + wasm_code.toString('hex')

// コントラクト名の ID が一意になるようにタイムスタンプを追加します
const contractName = 'contract' + Date.now()
// スマートコントラクトインスタンスを初期化します
let myContract = chain.ctr.contract(contractName, abi, chain.WASM)

スマートコントラクトのデプロイメント

myContract.new() を呼び出して、スマートコントラクトをブロックチェーンにデプロイします。バイトコードは 0x プレフィックスを含まない 16 進数形式である必要があります。

パラメーター

パラメーター必須説明
bytecodeはいstring0x プレフィックスを含まない 16 進数形式のコントラクトバイトコードです。
dataはいobjectfrom を含み、必要に応じて parameters を含むオブジェクトです。

`data` フィールド:

フィールド必須説明
fromはいstringこのトランザクションに使用するアカウント名です。
parametersはいArrayコントラクトの init() 関数に渡される引数(必要な場合)です。

const solc = require('@alipay/solc')
const contract = fs.readFileSync('./CreditManager.sol', { encoding: 'ascii' })
// 2 番目のパラメーターを 1 に設定してコンパイルを開始します
const output = solc.compile(contract, 1)
const abi = JSON.parse(output.contracts[':CreditManager'].interface)
const bytecode = output.contracts[':CreditManager'].bytecode

// コントラクト名の ID が一意になるようにタイムスタンプを追加します
const contractName = 'contract' + Date.now()
// スマートコントラクトインスタンスを初期化します
let myContract = chain.ctr.contract(contractName, abi)
// コントラクトをデプロイします。必要に応じて parameters フィールドを通じて init() に引数を渡します。
myContract.new(bytecode, {
  from: 'Tester001',
  // parameters: [param1, param2]
}, (err, contract, data) => {
  console.log(data)
})

スマートコントラクトの呼び出し

コントラクトインスタンス上で直接メソッド名を指定して呼び出します。複数の同時呼び出しがサポートされています。呼び出しが互いに依存する場合は、コールバックを使用してチェーン化してください。

パラメーター

パラメーター必須説明
メソッド引数いいえ可変呼び出すコントラクトメソッドに固有の引数です。
dataはいobjectfrom フィールドを含むオブジェクトです。

`data` フィールド:

フィールド必須説明
fromはいstringこのトランザクションに使用するアカウント名です。

例 1:デプロイメントコールバック内でメソッドを呼び出す

new() コールバック内でメソッド呼び出しをチェーン化し、デプロイ直後に実行します。

myContract.new(bytecode, {
  from: 'Tester001',
  // parameters: [param1, param2]
}, (err, contract, data) => {
  console.log(data)
  // Issue は 2 つの引数(アカウント ID と値)を必要とします
  myContract.Issue(
    '0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5',
    100,
    { from: 'Tester001' },
    (err, output, data) => {
      console.log('output is:', output)
    }
  )
})

例 2:コントラクトデプロイ後にメソッドを呼び出す

デプロイメントコールバックとは独立してコントラクトメソッドを呼び出します。同時呼び出しは並列で実行されます。呼び出し間の依存関係を表現するにはコールバックを使用してください。

myContract.new(bytecode, {
  from: 'Tester001',
  // parameters: [param1, param2]
}, (err, contract, data) => {
  console.log(data)
})

// デプロイメントと同時に Issue メソッドを呼び出します
myContract.Issue(
  '0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5',
  100,
  { from: 'Tester001' },
  (err, output, data) => {
    console.log('output is:', output)
  }
)

スマートコントラクトの更新

myContract.update() を呼び出して、デプロイ済みコントラクトのコードをブロックチェーン上で置き換えます。

警告

コントラクトの更新は慎重に行ってください。新しいコントラクトは、既存コントラクトのデータストレージレイアウトと互換性がある必要があります。通常は、この機能の使用を避けてください。

パラメーター

パラメーター必須説明
bytecodeはいstringランタイム バイトコードを 0x プレフィックスを含まない 16 進数形式で指定します。
dataはいobject空のオブジェクト {} を渡します。

ランタイムバイトコードの要件

コントラクトの更新には、完全なコンパイル出力ではなく ランタイム バイトコードが必要です。ランタイム バイトコードは --bin 出力のサブセットです。

ランタイム バイトコードは、次のいずれかの方法で取得できます。

  • --bin-runtime フラグを付けて solc コンパイラを実行します。「solc コンパイラ」をご参照ください。

  • コントラクトをローカルにデプロイし、トランザクションレシートからバイトコードを抽出します。

説明

以下で説明するローカルデプロイ手法は、Solidity 0.4.24 のみに適用されます。Solidity 0.6.4 以降の場合は、--bin-runtime を使用して solc コンパイラを実行し、直接 ランタイム バイトコードを取得してください。

この例では、solc-js を使用した完全な更新ワークフローを示します。

  1. solc-js を使用してコントラクト A をコンパイルします。

  2. スマートコントラクト A をデプロイします。

  3. スマートコントラクト A を呼び出します。

  4. スマートコントラクトコードを修正して、スマートコントラクト A' を取得します。

  5. solc-js を使用してスマートコントラクト A' をコンパイルします。

  6. コントラクト A' をローカルにデプロイして、ランタイム バイトコードを抽出します。

  7. A' の ランタイム バイトコードを使用して、スマートコントラクト A を更新します。

  8. スマートコントラクト A を呼び出して、更新ステータスを確認します。

const solc = require('@alipay/solc')
const contract = fs.readFileSync('./CreditManager.sol', { encoding: 'ascii' })
// 2 番目のパラメーターを 1 に設定してコンパイルを開始します
const output = solc.compile(contract, 1)
const abi = JSON.parse(output.contracts[':CreditManager'].interface)
const bytecode = output.contracts[':CreditManager'].bytecode

console.log('bytecode:', bytecode)
// コントラクト名の ID が一意になるようにタイムスタンプを追加します
let contractName = 'contract' + Date.now()
let myContract = chain.ctr.contract(contractName, abi)

// ステップ 1~3:コントラクト A をデプロイし、呼び出した後、修正版 A' をコンパイルします
myContract.new(bytecode, {
  from: 'Tester001',
}, (err, contract, data) => {
  console.log('contract new:', data)
  myContract.Issue('0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5', 100, { from: 'Tester001' }, (err, output, data) => {
    console.log('output1 is:', output)

    // CreditManager.sol を修正して CreditManagerPro.sol を取得します。
    // Issue メソッドで `credit[account] += value;` を `credit[account] += value * 2;` に変更します。
    // コントラクトストレージ定義は変更してはいけません。
    const contract_pro = fs.readFileSync('./CreditManagerPro.sol', { encoding: 'ascii' })
    // 2 番目のパラメーターを 1 に設定してコンパイルを開始します
    const output_pro = solc.compile(contract_pro, 1)
    const abi_pro = JSON.parse(output_pro.contracts[':CreditManager'].interface)
    const bytecode_pro = output_pro.contracts[':CreditManager'].bytecode
    myContract = chain.ctr.contract(contractName, abi_pro)

    // ステップ 5:A' をローカルにデプロイしてランタイムバイトコードを取得します
    myContract.new(bytecode_pro, {
      from: 'Tester001',
      local: true,       // ローカルにデプロイ — ブロックチェーンには書き込まれません
      block_number: 0    // コントラクト ID の競合を避けるためにジェネシスブロックを使用します
    }, (err, contract, data) => {
      console.log('local contract new result:', data)

      // ステップ 6:ローカルデプロイから取得したランタイムバイトコードを使用してコントラクト A を更新します
      myContract.update(data.receipt.output.replace('0x' + chain.EVM, ''), {
      }, (err, contract, data) => {
        console.log('contract update result:', data)

        // ステップ 7:更新後のコントラクトを呼び出して変更を検証します
        myContract.Issue('0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5', 100, { from: 'Tester001' }, (err, output, data) => {
          console.log('output2 is:', output.toString())

          // 残高を照会します。更新が成功していれば、結果は 300 になります。
          myContract.Query('0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5', { from: 'Tester001' }, (err, output, data) => {
            console.log('output3 is:', output.toString())
          })
        })
      })
    })
  })
})

期待される出力:

contract update result: {
  msg_type: 63,
  sequence: 7,
  return_code: 0,
  group_id: '0x0000000000000000000000000000000000000000',
  receipt: {
    result: 0,
    gas_used: 28610,
    log_entry: [ [Object] ],
    output: ''
  },
  block_number: 86114,
  transaction_index: 0,
  api: 'QueryTransactionReceipt',
  txhash: '0x40a72b99ec64fca0e1cc5025920de086a2523b4761ea5020c0f43a5240dc754a'
}
output2 is: true
output3 is: 300