Work requirements
(a) Generate a transaction that can be redeemed by the solutions x, y) of the following two linear equations:
x+y= (StudentID of First Half) and xy= (StudentID of Second Half)
[To ensure the existence of integer solutions, please Change the last digit of the two numbers on the right so that the numbers are both even or both odd].
(b) Redemption transactions. The redemption script should be as small as possible. In other words, an effective one scriptSig
should simply send two integers x and y to the stack. Make sure scriptPubKey
to use OP_ADD
sum in OP_SUB
.
Realization idea
This assignment looks like it asks you to solve an equation, and then verify that the square of your solution is correct. (But if you really use such a script to trade Bitcoin, then your own currency is not what others want to use, just use ORZ) It
has been said that the unlocking script is x and y, then the first to be pushed into the stack is x and y, then connect The next step is to verify whether x and y are the solutions of the square.
First copy xy again, because you need to verify that the two equations have to use both sides, it is used OP_2DUP
, its definition is like this, so you can assign the top two elements of the stack
elif sop == OP_2DUP:
check_args(2)
v1 = stack[-2]
v2 = stack[-1]
stack.append(v1)
stack.append(v2)
Then add x and y together and use the OP_ADD
script. When it is executed, it will pop
drop x and y and then put the result push
into the stack.
Then result
check whether this is consistent with the value in the original equation. The reason for this is OP_EQUALVERIFY
: Because it does not produce a return value, and use OP_EQUAL
will leave a true value in the stack that cannot be processed
elif sop == OP_EQUALVERIFY:
check_args(2)
v1 = stack[-1]
v2 = stack[-2]
if v1 == v2:
stack.pop()
stack.pop()
Then it’s almost the same idea as before, first get a subtraction result, then compare it with the value in the equation, use OP_EQUAL
verification, and leave a true value in the stack. Here you can see that it is not directly returning a false or true, but Returned \x01
or , should be the same function as true or false, empty is false, not empty is ture
elif sop == OP_EQUAL:
check_args(2)
v1 = stack.pop()
v2 = stack.pop()
if v1 == v2:
stack.append(b"\x01")
else:
stack.append(b"")
Implementation script
Lock script
OP_2DUP
OP_ADD
<StudentID of First Half>
OP_EQUALVERIFY
OP_SUB
<StudentID of Second Half>
OP_EQUAL
Unlock script
<X> #解方程的得到的xy值
<y>
Script running process
Complete script
<X>
<y>
-----
OP_2DUP
OP_ADD
<StudentID of First Half>
OP_EQUALVERIFY
OP_SUB
<StudentID of Second Half>
OP_EQUAL
working process
NULL #起始状态,栈内为空
<x> #x压栈
<x><y> #y压栈
<x><y><x><y> #OP_2DUP复制栈顶及栈顶下一个元素并压栈
<x><y><add_result> #OP_ADD弹出xy并且将xy相加的结果压栈
<x><y><add_result><stuid first> #学号前四位压栈
<x><y> #OP_EQUALVERIFY验证两个内容是否相等,相等则将其弹出
<sub_result> #OP_SUB弹出xy并且将xy相减的结果压栈
<sub_result><stuid second> #学号后三位压栈
ture #OP_EQUAL验证栈内的两个数值是否相等然后将true压栈
Fall into the pit
It was useless OP_EQUALVERIFY
and OP_EQUAL
used OP_NUMEQUALVERIFY
and. OP_NUMEQUAL
Looking at the source code of python-bitcoinlib, I only saw OP_NUMEQUALVERIFY
andOP_NUMEQUAL
elif opcode == OP_NUMEQUAL:
bn = long(bn1 == bn2)
stack.pop()
stack.pop()
stack.append(bitcoin.core._bignum.bn2vch(bn))
elif opcode == OP_NUMEQUALVERIFY:
bn = long(bn1 == bn2)
if not bn:
err_raiser(VerifyOpFailedError, opcode)
else:
# No exception, so time to pop the stack
stack.pop()
stack.pop()
return
It seems that there is no big problem, but instead of pushing it OP_NUMEQUAL
directly bn
onto the stack, it calls a function bitcoin.core._bignum.bn2vch
, which contains bignum
and has the bn
type long
. The called function may process bn, so there is no way to get ture in the end. The function also looked at the definition and so on, but did not see it clearly, because other functions were adjusted in the function. But it must be the pot of that function. (I wasted a share of coins, but fortunately, I divided ten shares)