如何在Corda中使用Oracle Service签署交易?

时间:2018-08-22 10:26:42

标签: corda

我正在尝试在Corda中使用Oracle服务签署交易。为此,我正在使用Corda文档中指定的功能。

fun commandValidator(elem: Command<*>): Boolean {
    require(services.myInfo.legalIdentities.first().owningKey in elem.signers && elem.value is Fix) {
        "Oracle received unknown command (not in signers or not Fix)."
    }
    val fix = elem.value as Fix
    val known = knownFixes[fix.of]
    if (known == null || known != fix)
        throw UnknownFix(fix.of)
    return true
}

但是当我尝试使用上述功能时,出现“ unknownFixes”和“ UnknownFix()”作为未解决的引用的错误。

a)如何解决此问题(如何声明或导入)?

b)这种方法是从Oracle Service进行交易签名的正确方法吗?

1 个答案:

答案 0 :(得分:0)

knownFixesUnknownFix是CorDapp特定的代码,定义为IRS sample的一部分。

作为oracle签名很简单:

@CordaService
class Oracle(val services: ServiceHub) : SingletonSerializeAsToken() {
    fun sign(ftx: FilteredTransaction): TransactionSignature {
        val myKey = services.myInfo.legalIdentities.first().owningKey
        return services.createSignature(ftx, myKey)
    }
}

但是您通常希望进行其他检查,以确保您对所签署的内容满意。支票由您决定。这是一个oracle的示例,它检查命令中嵌入的数字是否为质数:

@CordaService
class Oracle(val services: ServiceHub) : SingletonSerializeAsToken() {
    private val myKey = services.myInfo.legalIdentities.first().owningKey

    // Generates a list of natural numbers and filters out the non-primes.
    // The reason why prime numbers were chosen is because they are easy to reason about and reduce the mental load
    // for this tutorial application.
    // Clearly, most developers can generate a list of primes and all but the largest prime numbers can be verified
    // deterministically in reasonable time. As such, it would be possible to add a constraint in the
    // [PrimeContract.verify] function that checks the nth prime is indeed the specified number.
    private val primes = generateSequence(1) { it + 1 }.filter { BigInteger.valueOf(it.toLong()).isProbablePrime(16) }

    // Returns the Nth prime for N > 0.
    fun query(n: Int): Int {
        require(n > 0) { "n must be at least one." } // URL param is n not N.
        return primes.take(n).last()
    }

    // Signs over a transaction if the specified Nth prime for a particular N is correct.
    // This function takes a filtered transaction which is a partial Merkle tree. Any parts of the transaction which
    // the oracle doesn't need to see in order to verify the correctness of the nth prime have been removed. In this
    // case, all but the [PrimeContract.Create] commands have been removed. If the Nth prime is correct then the oracle
    // signs over the Merkle root (the hash) of the transaction.
    fun sign(ftx: FilteredTransaction): TransactionSignature {
        // Check the partial Merkle tree is valid.
        ftx.verify()

        /** Returns true if the component is an Create command that:
         *  - States the correct prime
         *  - Has the oracle listed as a signer
         */
        fun isCommandWithCorrectPrimeAndIAmSigner(elem: Any) = when {
            elem is Command<*> && elem.value is PrimeContract.Create -> {
                val cmdData = elem.value as PrimeContract.Create
                myKey in elem.signers && query(cmdData.n) == cmdData.nthPrime
            }
            else -> false
        }

        // Is it a Merkle tree we are willing to sign over?
        val isValidMerkleTree = ftx.checkWithFun(::isCommandWithCorrectPrimeAndIAmSigner)

        if (isValidMerkleTree) {
            return services.createSignature(ftx, myKey)
        } else {
            throw IllegalArgumentException("Oracle signature requested over invalid transaction.")
        }
    }
}