作業要求
(a)生成可通過以下兩個線性方程組的解x,y)贖回的交易:
x+y= (StudentID of First Half)和x-y= (StudentID of Second Half)
[為確保存在整數解,請更改右側兩個數字的最后一位,使數字都是偶數或都是奇數],
(b)贖回交易,贖回腳本應盡可能小,也就是說,一個有效的scriptSig應該是簡單地將兩個整數x和y發送到堆疊中,確保在scriptPubKey中使用了OP_ADD和OP_SUB,
實作思路
這個作業看起來就像是讓你解個方程,然后驗證一下你解的方乘對不對,(不過要是真的用這樣腳本交易位元幣那自己幣子不是別人想用就隨便用了嘛ORZ)
已經說了解鎖腳本就是x和y,那么首先壓入堆疊里的就是x和y,那接下就要驗證x和y是不是方乘的解,
首先先把xy復制一遍,因為需要驗證兩個方程得用兩邊,就用到了OP_2DUP,它的定義是這樣的,所以能把堆疊頂兩個元素賦值
elif sop == OP_2DUP:
check_args(2)
v1 = stack[-2]
v2 = stack[-1]
stack.append(v1)
stack.append(v2)
然后就把x和y加起來,用OP_ADD腳本,它在執行的時候會把x和ypop掉然后再把結果push進堆疊里
接著拿這個result和原方程里的值比較是否一致,這里之所以使用的是OP_EQUALVERIFY,是因為它不會產生一個回傳值,而使用OP_EQUAL會在堆疊里留下一個ture值沒法處理
elif sop == OP_EQUALVERIFY:
check_args(2)
v1 = stack[-1]
v2 = stack[-2]
if v1 == v2:
stack.pop()
stack.pop()
然后差不多和前面一樣的思路,先得到一個減的結果,然后和方程里的值比較,用OP_EQUAL驗證,在堆疊里留下一個true值,這里可以看到并不是直接回傳一個false或者true,而是回傳的\x01或者,應該是和true或者false一樣的功能,為空是false,不為空是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"")
實作腳本
加鎖腳本
OP_2DUP
OP_ADD
<StudentID of First Half>
OP_EQUALVERIFY
OP_SUB
<StudentID of Second Half>
OP_EQUAL
解鎖腳本
<X> #解方程的得到的xy值
<y>
腳本運行程序
完整的腳本
<X>
<y>
-----
OP_2DUP
OP_ADD
<StudentID of First Half>
OP_EQUALVERIFY
OP_SUB
<StudentID of Second Half>
OP_EQUAL
運行程序
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壓堆疊
掉進去的坑
沒有用OP_EQUALVERIFY和OP_EQUAL用了OP_NUMEQUALVERIFY和OP_NUMEQUAL
翻看python-bitcoinlib的原始碼,一開始只看到了OP_NUMEQUALVERIFY和OP_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
看似是沒有什么大問題的,不過OP_NUMEQUAL里并沒有直接把bn壓堆疊,反而是呼叫了一個函式bitcoin.core._bignum.bn2vch,里面有bignum而且bn型別為long,呼叫的函式可能對bn做了處理導致最后沒有辦法得到ture之類的,那個函式也看了下定義之類的沒有看得很清楚,因為函式里又調了別的函式,不過肯定是那個函式的鍋,(浪費了我一份幣子,還好當時分了十份)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/218629.html
標籤:其他
