standard_test.go 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. // Copyright (c) 2013-2017 The btcsuite developers
  2. // Use of this source code is governed by an ISC
  3. // license that can be found in the LICENSE file.
  4. package txscript
  5. import (
  6. "bytes"
  7. "encoding/hex"
  8. "reflect"
  9. "testing"
  10. "github.com/pkt-cash/pktd/btcutil/er"
  11. "github.com/pkt-cash/pktd/txscript/opcode"
  12. "github.com/pkt-cash/pktd/txscript/txscripterr"
  13. "github.com/pkt-cash/pktd/btcutil"
  14. "github.com/pkt-cash/pktd/chaincfg"
  15. "github.com/pkt-cash/pktd/wire"
  16. )
  17. // mustParseShortForm parses the passed short form script and returns the
  18. // resulting bytes. It panics if an error occurs. This is only used in the
  19. // tests as a helper since the only way it can fail is if there is an error in
  20. // the test source code.
  21. func mustParseShortForm(script string) []byte {
  22. s, err := parseShortForm(script)
  23. if err != nil {
  24. panic("invalid short form script in test source: err " +
  25. err.String() + ", script: " + script)
  26. }
  27. return s
  28. }
  29. // newAddressPubKey returns a new btcutil.AddressPubKey from the provided
  30. // serialized public key. It panics if an error occurs. This is only used in
  31. // the tests as a helper since the only way it can fail is if there is an error
  32. // in the test source code.
  33. func newAddressPubKey(serializedPubKey []byte) btcutil.Address {
  34. addr, err := btcutil.NewAddressPubKey(serializedPubKey,
  35. &chaincfg.MainNetParams)
  36. if err != nil {
  37. panic("invalid public key in test source")
  38. }
  39. return addr
  40. }
  41. // newAddressPubKeyHash returns a new btcutil.AddressPubKeyHash from the
  42. // provided hash. It panics if an error occurs. This is only used in the tests
  43. // as a helper since the only way it can fail is if there is an error in the
  44. // test source code.
  45. func newAddressPubKeyHash(pkHash []byte) btcutil.Address {
  46. addr, err := btcutil.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams)
  47. if err != nil {
  48. panic("invalid public key hash in test source")
  49. }
  50. return addr
  51. }
  52. // newAddressScriptHash returns a new btcutil.AddressScriptHash from the
  53. // provided hash. It panics if an error occurs. This is only used in the tests
  54. // as a helper since the only way it can fail is if there is an error in the
  55. // test source code.
  56. func newAddressScriptHash(scriptHash []byte) btcutil.Address {
  57. addr, err := btcutil.NewAddressScriptHashFromHash(scriptHash,
  58. &chaincfg.MainNetParams)
  59. if err != nil {
  60. panic("invalid script hash in test source")
  61. }
  62. return addr
  63. }
  64. // TestExtractPkScriptAddrs ensures that extracting the type, addresses, and
  65. // number of required signatures from PkScripts works as intended.
  66. func TestExtractPkScriptAddrs(t *testing.T) {
  67. tests := []struct {
  68. name string
  69. script []byte
  70. addrs []btcutil.Address
  71. reqSigs int
  72. class ScriptClass
  73. }{
  74. {
  75. name: "standard p2pk with compressed pubkey (0x02)",
  76. script: hexToBytes("2102192d74d0cb94344c9569c2e779015" +
  77. "73d8d7903c3ebec3a957724895dca52c6b4ac"),
  78. addrs: []btcutil.Address{
  79. newAddressPubKey(hexToBytes("02192d74d0cb9434" +
  80. "4c9569c2e77901573d8d7903c3ebec3a9577" +
  81. "24895dca52c6b4")),
  82. },
  83. reqSigs: 1,
  84. class: PubKeyTy,
  85. },
  86. {
  87. name: "standard p2pk with uncompressed pubkey (0x04)",
  88. script: hexToBytes("410411db93e1dcdb8a016b49840f8c53b" +
  89. "c1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddf" +
  90. "b84ccf9744464f82e160bfa9b8b64f9d4c03f999b864" +
  91. "3f656b412a3ac"),
  92. addrs: []btcutil.Address{
  93. newAddressPubKey(hexToBytes("0411db93e1dcdb8a" +
  94. "016b49840f8c53bc1eb68a382e97b1482eca" +
  95. "d7b148a6909a5cb2e0eaddfb84ccf9744464" +
  96. "f82e160bfa9b8b64f9d4c03f999b8643f656" +
  97. "b412a3")),
  98. },
  99. reqSigs: 1,
  100. class: PubKeyTy,
  101. },
  102. {
  103. name: "standard p2pk with hybrid pubkey (0x06)",
  104. script: hexToBytes("4106192d74d0cb94344c9569c2e779015" +
  105. "73d8d7903c3ebec3a957724895dca52c6b40d4526483" +
  106. "8c0bd96852662ce6a847b197376830160c6d2eb5e6a4" +
  107. "c44d33f453eac"),
  108. addrs: []btcutil.Address{
  109. newAddressPubKey(hexToBytes("06192d74d0cb9434" +
  110. "4c9569c2e77901573d8d7903c3ebec3a9577" +
  111. "24895dca52c6b40d45264838c0bd96852662" +
  112. "ce6a847b197376830160c6d2eb5e6a4c44d3" +
  113. "3f453e")),
  114. },
  115. reqSigs: 1,
  116. class: PubKeyTy,
  117. },
  118. {
  119. name: "standard p2pk with compressed pubkey (0x03)",
  120. script: hexToBytes("2103b0bd634234abbb1ba1e986e884185" +
  121. "c61cf43e001f9137f23c2c409273eb16e65ac"),
  122. addrs: []btcutil.Address{
  123. newAddressPubKey(hexToBytes("03b0bd634234abbb" +
  124. "1ba1e986e884185c61cf43e001f9137f23c2" +
  125. "c409273eb16e65")),
  126. },
  127. reqSigs: 1,
  128. class: PubKeyTy,
  129. },
  130. {
  131. name: "2nd standard p2pk with uncompressed pubkey (0x04)",
  132. script: hexToBytes("4104b0bd634234abbb1ba1e986e884185" +
  133. "c61cf43e001f9137f23c2c409273eb16e6537a576782" +
  134. "eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3" +
  135. "c1e0908ef7bac"),
  136. addrs: []btcutil.Address{
  137. newAddressPubKey(hexToBytes("04b0bd634234abbb" +
  138. "1ba1e986e884185c61cf43e001f9137f23c2" +
  139. "c409273eb16e6537a576782eba668a7ef8bd" +
  140. "3b3cfb1edb7117ab65129b8a2e681f3c1e09" +
  141. "08ef7b")),
  142. },
  143. reqSigs: 1,
  144. class: PubKeyTy,
  145. },
  146. {
  147. name: "standard p2pk with hybrid pubkey (0x07)",
  148. script: hexToBytes("4107b0bd634234abbb1ba1e986e884185" +
  149. "c61cf43e001f9137f23c2c409273eb16e6537a576782" +
  150. "eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3" +
  151. "c1e0908ef7bac"),
  152. addrs: []btcutil.Address{
  153. newAddressPubKey(hexToBytes("07b0bd634234abbb" +
  154. "1ba1e986e884185c61cf43e001f9137f23c2" +
  155. "c409273eb16e6537a576782eba668a7ef8bd" +
  156. "3b3cfb1edb7117ab65129b8a2e681f3c1e09" +
  157. "08ef7b")),
  158. },
  159. reqSigs: 1,
  160. class: PubKeyTy,
  161. },
  162. {
  163. name: "standard p2pkh",
  164. script: hexToBytes("76a914ad06dd6ddee55cbca9a9e3713bd" +
  165. "7587509a3056488ac"),
  166. addrs: []btcutil.Address{
  167. newAddressPubKeyHash(hexToBytes("ad06dd6ddee5" +
  168. "5cbca9a9e3713bd7587509a30564")),
  169. },
  170. reqSigs: 1,
  171. class: PubKeyHashTy,
  172. },
  173. {
  174. name: "standard p2sh",
  175. script: hexToBytes("a91463bcc565f9e68ee0189dd5cc67f1b" +
  176. "0e5f02f45cb87"),
  177. addrs: []btcutil.Address{
  178. newAddressScriptHash(hexToBytes("63bcc565f9e6" +
  179. "8ee0189dd5cc67f1b0e5f02f45cb")),
  180. },
  181. reqSigs: 1,
  182. class: ScriptHashTy,
  183. },
  184. // from real tx 60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1, vout 0
  185. {
  186. name: "standard 1 of 2 multisig",
  187. script: hexToBytes("514104cc71eb30d653c0c3163990c47b9" +
  188. "76f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a47" +
  189. "3e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d1" +
  190. "1fcdd0d348ac4410461cbdcc5409fb4b4d42b51d3338" +
  191. "1354d80e550078cb532a34bfa2fcfdeb7d76519aecc6" +
  192. "2770f5b0e4ef8551946d8a540911abe3e7854a26f39f" +
  193. "58b25c15342af52ae"),
  194. addrs: []btcutil.Address{
  195. newAddressPubKey(hexToBytes("04cc71eb30d653c0" +
  196. "c3163990c47b976f3fb3f37cccdcbedb169a" +
  197. "1dfef58bbfbfaff7d8a473e7e2e6d317b87b" +
  198. "afe8bde97e3cf8f065dec022b51d11fcdd0d" +
  199. "348ac4")),
  200. newAddressPubKey(hexToBytes("0461cbdcc5409fb4" +
  201. "b4d42b51d33381354d80e550078cb532a34b" +
  202. "fa2fcfdeb7d76519aecc62770f5b0e4ef855" +
  203. "1946d8a540911abe3e7854a26f39f58b25c1" +
  204. "5342af")),
  205. },
  206. reqSigs: 1,
  207. class: MultiSigTy,
  208. },
  209. // from real tx d646f82bd5fbdb94a36872ce460f97662b80c3050ad3209bef9d1e398ea277ab, vin 1
  210. {
  211. name: "standard 2 of 3 multisig",
  212. script: hexToBytes("524104cb9c3c222c5f7a7d3b9bd152f36" +
  213. "3a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e2" +
  214. "9105f24de20ff463c1c91fcf3bf662cdde4783d4799f" +
  215. "787cb7c08869b4104ccc588420deeebea22a7e900cc8" +
  216. "b68620d2212c374604e3487ca08f1ff3ae12bdc63951" +
  217. "4d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e" +
  218. "71e610b036aa24104ab47ad1939edcb3db65f7fedea6" +
  219. "2bbf781c5410d3f22a7a3a56ffefb2238af8627363bd" +
  220. "f2ed97c1f89784a1aecdb43384f11d2acc64443c7fc2" +
  221. "99cef0400421a53ae"),
  222. addrs: []btcutil.Address{
  223. newAddressPubKey(hexToBytes("04cb9c3c222c5f7a" +
  224. "7d3b9bd152f363a0b6d54c9eb312c4d4f9af" +
  225. "1e8551b6c421a6a4ab0e29105f24de20ff46" +
  226. "3c1c91fcf3bf662cdde4783d4799f787cb7c" +
  227. "08869b")),
  228. newAddressPubKey(hexToBytes("04ccc588420deeeb" +
  229. "ea22a7e900cc8b68620d2212c374604e3487" +
  230. "ca08f1ff3ae12bdc639514d0ec8612a2d3c5" +
  231. "19f084d9a00cbbe3b53d071e9b09e71e610b" +
  232. "036aa2")),
  233. newAddressPubKey(hexToBytes("04ab47ad1939edcb" +
  234. "3db65f7fedea62bbf781c5410d3f22a7a3a5" +
  235. "6ffefb2238af8627363bdf2ed97c1f89784a" +
  236. "1aecdb43384f11d2acc64443c7fc299cef04" +
  237. "00421a")),
  238. },
  239. reqSigs: 2,
  240. class: MultiSigTy,
  241. },
  242. // The below are nonstandard script due to things such as
  243. // invalid pubkeys, failure to parse, and not being of a
  244. // standard form.
  245. {
  246. name: "p2pk with uncompressed pk missing OP_CHECKSIG",
  247. script: hexToBytes("410411db93e1dcdb8a016b49840f8c53b" +
  248. "c1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddf" +
  249. "b84ccf9744464f82e160bfa9b8b64f9d4c03f999b864" +
  250. "3f656b412a3"),
  251. addrs: nil,
  252. reqSigs: 0,
  253. class: NonStandardTy,
  254. },
  255. {
  256. name: "valid signature from a sigscript - no addresses",
  257. script: hexToBytes("47304402204e45e16932b8af514961a1d" +
  258. "3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41022" +
  259. "0181522ec8eca07de4860a4acdd12909d831cc56cbba" +
  260. "c4622082221a8768d1d0901"),
  261. addrs: nil,
  262. reqSigs: 0,
  263. class: NonStandardTy,
  264. },
  265. // Note the technically the pubkey is the second item on the
  266. // stack, but since the address extraction intentionally only
  267. // works with standard PkScripts, this should not return any
  268. // addresses.
  269. {
  270. name: "valid sigscript to reedeem p2pk - no addresses",
  271. script: hexToBytes("493046022100ddc69738bf2336318e4e0" +
  272. "41a5a77f305da87428ab1606f023260017854350ddc0" +
  273. "22100817af09d2eec36862d16009852b7e3a0f6dd765" +
  274. "98290b7834e1453660367e07a014104cd4240c198e12" +
  275. "523b6f9cb9f5bed06de1ba37e96a1bbd13745fcf9d11" +
  276. "c25b1dff9a519675d198804ba9962d3eca2d5937d58e" +
  277. "5a75a71042d40388a4d307f887d"),
  278. addrs: nil,
  279. reqSigs: 0,
  280. class: NonStandardTy,
  281. },
  282. // from real tx 691dd277dc0e90a462a3d652a1171686de49cf19067cd33c7df0392833fb986a, vout 0
  283. // invalid public keys
  284. {
  285. name: "1 of 3 multisig with invalid pubkeys",
  286. script: hexToBytes("51411c2200007353455857696b696c656" +
  287. "16b73204361626c6567617465204261636b75700a0a6" +
  288. "361626c65676174652d3230313031323034313831312" +
  289. "e377a0a0a446f41776e6c6f61642074686520666f6c6" +
  290. "c6f77696e67207472616e73616374696f6e732077697" +
  291. "468205361746f736869204e616b616d6f746f2773206" +
  292. "46f776e6c6f61416420746f6f6c2077686963680a636" +
  293. "16e20626520666f756e6420696e207472616e7361637" +
  294. "4696f6e2036633533636439383731313965663739376" +
  295. "435616463636453ae"),
  296. addrs: []btcutil.Address{},
  297. reqSigs: 1,
  298. class: MultiSigTy,
  299. },
  300. // from real tx: 691dd277dc0e90a462a3d652a1171686de49cf19067cd33c7df0392833fb986a, vout 44
  301. // invalid public keys
  302. {
  303. name: "1 of 3 multisig with invalid pubkeys 2",
  304. script: hexToBytes("514134633365633235396337346461636" +
  305. "536666430383862343463656638630a6336366263313" +
  306. "93936633862393461333831316233363536313866653" +
  307. "16539623162354136636163636539393361333938386" +
  308. "134363966636336643664616266640a3236363363666" +
  309. "13963663463303363363039633539336333653931666" +
  310. "56465373032392131323364643432643235363339643" +
  311. "338613663663530616234636434340a00000053ae"),
  312. addrs: []btcutil.Address{},
  313. reqSigs: 1,
  314. class: MultiSigTy,
  315. },
  316. {
  317. name: "empty script",
  318. script: []byte{},
  319. addrs: nil,
  320. reqSigs: 0,
  321. class: NonStandardTy,
  322. },
  323. {
  324. name: "script that does not parse",
  325. script: []byte{opcode.OP_DATA_45},
  326. addrs: nil,
  327. reqSigs: 0,
  328. class: NonStandardTy,
  329. },
  330. }
  331. t.Logf("Running %d tests.", len(tests))
  332. for i, test := range tests {
  333. class, addrs, reqSigs, err := ExtractPkScriptAddrs(
  334. test.script, &chaincfg.MainNetParams)
  335. if err != nil {
  336. if test.name != "script that does not parse" {
  337. t.Errorf("ExtractPkScriptAddrs() returned %v in test %v",
  338. err, test.name)
  339. continue
  340. }
  341. } else if test.name == "script that does not parse" {
  342. t.Errorf("ExtractPkScriptAddrs() expected an error")
  343. }
  344. if !reflect.DeepEqual(addrs, test.addrs) {
  345. t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
  346. "addresses\ngot %v\nwant %v", i, test.name,
  347. addrs, test.addrs)
  348. continue
  349. }
  350. if reqSigs != test.reqSigs {
  351. t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
  352. "number of required signatures - got %d, "+
  353. "want %d", i, test.name, reqSigs, test.reqSigs)
  354. continue
  355. }
  356. if class != test.class {
  357. t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
  358. "script type - got %s, want %s", i, test.name,
  359. class, test.class)
  360. continue
  361. }
  362. }
  363. }
  364. // TestCalcScriptInfo ensures the CalcScriptInfo provides the expected results
  365. // for various valid and invalid script pairs.
  366. func TestCalcScriptInfo(t *testing.T) {
  367. tests := []struct {
  368. name string
  369. sigScript string
  370. pkScript string
  371. witness []string
  372. bip16 bool
  373. segwit bool
  374. scriptInfo ScriptInfo
  375. scriptInfoErr er.R
  376. }{
  377. {
  378. // Invented scripts, the hashes do not match
  379. // Truncated version of test below:
  380. name: "pkscript doesn't parse",
  381. sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
  382. "SWAP ABS EQUAL",
  383. pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
  384. "3152205ec4f59c",
  385. bip16: true,
  386. scriptInfoErr: txscripterr.ScriptError(txscripterr.ErrMalformedPush, ""),
  387. },
  388. {
  389. name: "sigScript doesn't parse",
  390. // Truncated version of p2sh script below.
  391. sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
  392. "SWAP ABS",
  393. pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
  394. "3152205ec4f59c74 EQUAL",
  395. bip16: true,
  396. scriptInfoErr: txscripterr.ScriptError(txscripterr.ErrMalformedPush, ""),
  397. },
  398. {
  399. // Invented scripts, the hashes do not match
  400. name: "p2sh standard script",
  401. sigScript: "1 81 DATA_25 DUP HASH160 DATA_20 0x010203" +
  402. "0405060708090a0b0c0d0e0f1011121314 EQUALVERIFY " +
  403. "CHECKSIG",
  404. pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
  405. "3152205ec4f59c74 EQUAL",
  406. bip16: true,
  407. scriptInfo: ScriptInfo{
  408. PkScriptClass: ScriptHashTy,
  409. NumInputs: 3,
  410. ExpectedInputs: 3, // nonstandard p2sh.
  411. SigOps: 1,
  412. },
  413. },
  414. {
  415. // from 567a53d1ce19ce3d07711885168484439965501536d0d0294c5d46d46c10e53b
  416. // from the blockchain.
  417. name: "p2sh nonstandard script",
  418. sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
  419. "SWAP ABS EQUAL",
  420. pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
  421. "3152205ec4f59c74 EQUAL",
  422. bip16: true,
  423. scriptInfo: ScriptInfo{
  424. PkScriptClass: ScriptHashTy,
  425. NumInputs: 3,
  426. ExpectedInputs: -1, // nonstandard p2sh.
  427. SigOps: 0,
  428. },
  429. },
  430. {
  431. // Script is invented, numbers all fake.
  432. name: "multisig script",
  433. // Extra 0 arg on the end for OP_CHECKMULTISIG bug.
  434. sigScript: "1 1 1 0",
  435. pkScript: "3 " +
  436. "DATA_33 0x0102030405060708090a0b0c0d0e0f1011" +
  437. "12131415161718191a1b1c1d1e1f2021 DATA_33 " +
  438. "0x0102030405060708090a0b0c0d0e0f101112131415" +
  439. "161718191a1b1c1d1e1f2021 DATA_33 0x010203040" +
  440. "5060708090a0b0c0d0e0f101112131415161718191a1" +
  441. "b1c1d1e1f2021 3 CHECKMULTISIG",
  442. bip16: true,
  443. scriptInfo: ScriptInfo{
  444. PkScriptClass: MultiSigTy,
  445. NumInputs: 4,
  446. ExpectedInputs: 4,
  447. SigOps: 3,
  448. },
  449. },
  450. {
  451. // A v0 p2wkh spend.
  452. name: "p2wkh script",
  453. pkScript: "OP_0 DATA_20 0x365ab47888e150ff46f8d51bce36dcd680f1283f",
  454. witness: []string{
  455. "3045022100ee9fe8f9487afa977" +
  456. "6647ebcf0883ce0cd37454d7ce19889d34ba2c9" +
  457. "9ce5a9f402200341cb469d0efd3955acb9e46" +
  458. "f568d7e2cc10f9084aaff94ced6dc50a59134ad01",
  459. "03f0000d0639a22bfaf217e4c9428" +
  460. "9c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
  461. },
  462. segwit: true,
  463. scriptInfo: ScriptInfo{
  464. PkScriptClass: WitnessV0PubKeyHashTy,
  465. NumInputs: 2,
  466. ExpectedInputs: 2,
  467. SigOps: 1,
  468. },
  469. },
  470. {
  471. // Nested p2sh v0
  472. name: "p2wkh nested inside p2sh",
  473. pkScript: "HASH160 DATA_20 " +
  474. "0xb3a84b564602a9d68b4c9f19c2ea61458ff7826c EQUAL",
  475. sigScript: "DATA_22 0x0014ad0ffa2e387f07e7ead14dc56d5a97dbd6ff5a23",
  476. witness: []string{
  477. "3045022100cb1c2ac1ff1d57d" +
  478. "db98f7bdead905f8bf5bcc8641b029ce8eef25" +
  479. "c75a9e22a4702203be621b5c86b771288706be5" +
  480. "a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201",
  481. "03f0000d0639a22bfaf217e4c9" +
  482. "4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
  483. },
  484. segwit: true,
  485. bip16: true,
  486. scriptInfo: ScriptInfo{
  487. PkScriptClass: ScriptHashTy,
  488. NumInputs: 3,
  489. ExpectedInputs: 3,
  490. SigOps: 1,
  491. },
  492. },
  493. {
  494. // A v0 p2wsh spend.
  495. name: "p2wsh spend of a p2wkh witness script",
  496. pkScript: "0 DATA_32 0xe112b88a0cd87ba387f44" +
  497. "9d443ee2596eb353beb1f0351ab2cba8909d875db23",
  498. witness: []string{
  499. "3045022100cb1c2ac1ff1d57d" +
  500. "db98f7bdead905f8bf5bcc8641b029ce8eef25" +
  501. "c75a9e22a4702203be621b5c86b771288706be5" +
  502. "a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201",
  503. "03f0000d0639a22bfaf217e4c9" +
  504. "4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
  505. "76a914064977cb7b4a2e0c9680df0ef696e9e0e296b39988ac",
  506. },
  507. segwit: true,
  508. scriptInfo: ScriptInfo{
  509. PkScriptClass: WitnessV0ScriptHashTy,
  510. NumInputs: 3,
  511. ExpectedInputs: 3,
  512. SigOps: 1,
  513. },
  514. },
  515. }
  516. for _, test := range tests {
  517. sigScript := mustParseShortForm(test.sigScript)
  518. pkScript := mustParseShortForm(test.pkScript)
  519. var witness wire.TxWitness
  520. for _, witElement := range test.witness {
  521. wit, err := hex.DecodeString(witElement)
  522. if err != nil {
  523. t.Fatalf("unable to decode witness "+
  524. "element: %v", err)
  525. }
  526. witness = append(witness, wit)
  527. }
  528. si, err := CalcScriptInfo(sigScript, pkScript, witness,
  529. test.bip16, test.segwit)
  530. if e := tstCheckScriptError(err, test.scriptInfoErr); e != nil {
  531. t.Errorf("scriptinfo test %q: %v", test.name, e)
  532. continue
  533. }
  534. if err != nil {
  535. continue
  536. }
  537. if *si != test.scriptInfo {
  538. t.Errorf("%s: scriptinfo doesn't match expected. "+
  539. "got: %q expected %q", test.name, *si,
  540. test.scriptInfo)
  541. continue
  542. }
  543. }
  544. }
  545. // bogusAddress implements the btcutil.Address interface so the tests can ensure
  546. // unsupported address types are handled properly.
  547. type bogusAddress struct{}
  548. // EncodeAddress simply returns an empty string. It exists to satisfy the
  549. // btcutil.Address interface.
  550. func (b *bogusAddress) EncodeAddress() string {
  551. return ""
  552. }
  553. // ScriptAddress simply returns an empty byte slice. It exists to satisfy the
  554. // btcutil.Address interface.
  555. func (b *bogusAddress) ScriptAddress() []byte {
  556. return nil
  557. }
  558. // IsForNet lies blatantly to satisfy the btcutil.Address interface.
  559. func (b *bogusAddress) IsForNet(chainParams *chaincfg.Params) bool {
  560. return true // why not?
  561. }
  562. // String simply returns an empty string. It exists to satisfy the
  563. // btcutil.Address interface.
  564. func (b *bogusAddress) String() string {
  565. return ""
  566. }
  567. // TestPayToAddrScript ensures the PayToAddrScript function generates the
  568. // correct scripts for the various types of addresses.
  569. func TestPayToAddrScript(t *testing.T) {
  570. // 1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX
  571. p2pkhMain, err := btcutil.NewAddressPubKeyHash(hexToBytes("e34cce70c86"+
  572. "373273efcc54ce7d2a491bb4a0e84"), &chaincfg.MainNetParams)
  573. if err != nil {
  574. t.Fatalf("Unable to create public key hash address: %v", err)
  575. }
  576. // Taken from transaction:
  577. // b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d
  578. p2shMain, _ := btcutil.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
  579. "c87986efa84c37c0519929019ef86eb5b4"), &chaincfg.MainNetParams)
  580. if err != nil {
  581. t.Fatalf("Unable to create script hash address: %v", err)
  582. }
  583. // mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
  584. p2pkCompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("02192d"+
  585. "74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
  586. &chaincfg.MainNetParams)
  587. if err != nil {
  588. t.Fatalf("Unable to create pubkey address (compressed): %v",
  589. err)
  590. }
  591. p2pkCompressed2Main, err := btcutil.NewAddressPubKey(hexToBytes("03b0b"+
  592. "d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
  593. &chaincfg.MainNetParams)
  594. if err != nil {
  595. t.Fatalf("Unable to create pubkey address (compressed 2): %v",
  596. err)
  597. }
  598. p2pkUncompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("0411"+
  599. "db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
  600. "cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
  601. "12a3"), &chaincfg.MainNetParams)
  602. if err != nil {
  603. t.Fatalf("Unable to create pubkey address (uncompressed): %v",
  604. err)
  605. }
  606. // Errors used in the tests below defined here for convenience and to
  607. // keep the horizontal test size shorter.
  608. errUnsupportedAddress := txscripterr.ScriptError(txscripterr.ErrUnsupportedAddress, "")
  609. tests := []struct {
  610. in btcutil.Address
  611. expected string
  612. err er.R
  613. }{
  614. // pay-to-pubkey-hash address on mainnet
  615. {
  616. p2pkhMain,
  617. "DUP HASH160 DATA_20 0xe34cce70c86373273efcc54ce7d2a4" +
  618. "91bb4a0e8488 CHECKSIG",
  619. nil,
  620. },
  621. // pay-to-script-hash address on mainnet
  622. {
  623. p2shMain,
  624. "HASH160 DATA_20 0xe8c300c87986efa84c37c0519929019ef8" +
  625. "6eb5b4 EQUAL",
  626. nil,
  627. },
  628. // pay-to-pubkey address on mainnet. compressed key.
  629. {
  630. p2pkCompressedMain,
  631. "DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c3" +
  632. "ebec3a957724895dca52c6b4 CHECKSIG",
  633. nil,
  634. },
  635. // pay-to-pubkey address on mainnet. compressed key (other way).
  636. {
  637. p2pkCompressed2Main,
  638. "DATA_33 0x03b0bd634234abbb1ba1e986e884185c61cf43e001" +
  639. "f9137f23c2c409273eb16e65 CHECKSIG",
  640. nil,
  641. },
  642. // pay-to-pubkey address on mainnet. uncompressed key.
  643. {
  644. p2pkUncompressedMain,
  645. "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
  646. "97b1482ecad7b148a6909a5cb2e0eaddfb84ccf97444" +
  647. "64f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 " +
  648. "CHECKSIG",
  649. nil,
  650. },
  651. // Supported address types with nil pointers.
  652. {(*btcutil.AddressPubKeyHash)(nil), "", errUnsupportedAddress},
  653. {(*btcutil.AddressScriptHash)(nil), "", errUnsupportedAddress},
  654. {(*btcutil.AddressPubKey)(nil), "", errUnsupportedAddress},
  655. // Unsupported address type.
  656. {&bogusAddress{}, "", errUnsupportedAddress},
  657. }
  658. t.Logf("Running %d tests", len(tests))
  659. for i, test := range tests {
  660. pkScript, err := PayToAddrScript(test.in)
  661. if e := tstCheckScriptError(err, test.err); e != nil {
  662. t.Errorf("PayToAddrScript #%d unexpected error - "+
  663. "got %v, want %v", i, err, test.err)
  664. continue
  665. }
  666. expected := mustParseShortForm(test.expected)
  667. if !bytes.Equal(pkScript, expected) {
  668. t.Errorf("PayToAddrScript #%d got: %x\nwant: %x",
  669. i, pkScript, expected)
  670. continue
  671. }
  672. }
  673. }
  674. // TestMultiSigScript ensures the MultiSigScript function returns the expected
  675. // scripts and errors.
  676. func TestMultiSigScript(t *testing.T) {
  677. // mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
  678. p2pkCompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("02192d"+
  679. "74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
  680. &chaincfg.MainNetParams)
  681. if err != nil {
  682. t.Fatalf("Unable to create pubkey address (compressed): %v",
  683. err)
  684. }
  685. p2pkCompressed2Main, err := btcutil.NewAddressPubKey(hexToBytes("03b0b"+
  686. "d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
  687. &chaincfg.MainNetParams)
  688. if err != nil {
  689. t.Fatalf("Unable to create pubkey address (compressed 2): %v",
  690. err)
  691. }
  692. p2pkUncompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("0411"+
  693. "db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
  694. "cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
  695. "12a3"), &chaincfg.MainNetParams)
  696. if err != nil {
  697. t.Fatalf("Unable to create pubkey address (uncompressed): %v",
  698. err)
  699. }
  700. tests := []struct {
  701. keys []*btcutil.AddressPubKey
  702. nrequired int
  703. expected string
  704. err er.R
  705. }{
  706. {
  707. []*btcutil.AddressPubKey{
  708. p2pkCompressedMain,
  709. p2pkCompressed2Main,
  710. },
  711. 1,
  712. "1 DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c" +
  713. "3ebec3a957724895dca52c6b4 DATA_33 0x03b0bd634" +
  714. "234abbb1ba1e986e884185c61cf43e001f9137f23c2c4" +
  715. "09273eb16e65 2 CHECKMULTISIG",
  716. nil,
  717. },
  718. {
  719. []*btcutil.AddressPubKey{
  720. p2pkCompressedMain,
  721. p2pkCompressed2Main,
  722. },
  723. 2,
  724. "2 DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c" +
  725. "3ebec3a957724895dca52c6b4 DATA_33 0x03b0bd634" +
  726. "234abbb1ba1e986e884185c61cf43e001f9137f23c2c4" +
  727. "09273eb16e65 2 CHECKMULTISIG",
  728. nil,
  729. },
  730. {
  731. []*btcutil.AddressPubKey{
  732. p2pkCompressedMain,
  733. p2pkCompressed2Main,
  734. },
  735. 3,
  736. "",
  737. txscripterr.ScriptError(txscripterr.ErrTooManyRequiredSigs, ""),
  738. },
  739. {
  740. []*btcutil.AddressPubKey{
  741. p2pkUncompressedMain,
  742. },
  743. 1,
  744. "1 DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382" +
  745. "e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf97444" +
  746. "64f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 " +
  747. "1 CHECKMULTISIG",
  748. nil,
  749. },
  750. {
  751. []*btcutil.AddressPubKey{
  752. p2pkUncompressedMain,
  753. },
  754. 2,
  755. "",
  756. txscripterr.ScriptError(txscripterr.ErrTooManyRequiredSigs, ""),
  757. },
  758. }
  759. t.Logf("Running %d tests", len(tests))
  760. for i, test := range tests {
  761. script, err := MultiSigScript(test.keys, test.nrequired)
  762. if e := tstCheckScriptError(err, test.err); e != nil {
  763. t.Errorf("MultiSigScript #%d: %v", i, e)
  764. continue
  765. }
  766. expected := mustParseShortForm(test.expected)
  767. if !bytes.Equal(script, expected) {
  768. t.Errorf("MultiSigScript #%d got: %x\nwant: %x",
  769. i, script, expected)
  770. continue
  771. }
  772. }
  773. }
  774. // TestCalcMultiSigStats ensures the CalcMutliSigStats function returns the
  775. // expected errors.
  776. func TestCalcMultiSigStats(t *testing.T) {
  777. tests := []struct {
  778. name string
  779. script string
  780. err er.R
  781. }{
  782. {
  783. name: "short script",
  784. script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" +
  785. "e03909a67962e0ea1f61d",
  786. err: txscripterr.ScriptError(txscripterr.ErrMalformedPush, ""),
  787. },
  788. {
  789. name: "stack underflow",
  790. script: "RETURN DATA_41 0x046708afdb0fe5548271967f1a" +
  791. "67130b7105cd6a828e03909a67962e0ea1f61deb649f6" +
  792. "bc3f4cef308",
  793. err: txscripterr.ScriptError(txscripterr.ErrNotMultisigScript, ""),
  794. },
  795. {
  796. name: "multisig script",
  797. script: "0 DATA_72 0x30450220106a3e4ef0b51b764a2887226" +
  798. "2ffef55846514dacbdcbbdd652c849d395b4384022100" +
  799. "e03ae554c3cbb40600d31dd46fc33f25e47bf8525b1fe" +
  800. "07282e3b6ecb5f3bb2801 CODESEPARATOR 1 DATA_33 " +
  801. "0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" +
  802. "0357b3a7886211ab414d55a 1 CHECKMULTISIG",
  803. err: nil,
  804. },
  805. }
  806. for i, test := range tests {
  807. script := mustParseShortForm(test.script)
  808. _, _, err := CalcMultiSigStats(script)
  809. if e := tstCheckScriptError(err, test.err); e != nil {
  810. t.Errorf("CalcMultiSigStats #%d (%s): %v", i, test.name,
  811. e)
  812. continue
  813. }
  814. }
  815. }
  816. // scriptClassTests houses several test scripts used to ensure various class
  817. // determination is working as expected. It's defined as a test global versus
  818. // inside a function scope since this spans both the standard tests and the
  819. // consensus tests (pay-to-script-hash is part of consensus).
  820. var scriptClassTests = []struct {
  821. name string
  822. script string
  823. class ScriptClass
  824. }{
  825. {
  826. name: "Pay Pubkey",
  827. script: "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
  828. "97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e16" +
  829. "0bfa9b8b64f9d4c03f999b8643f656b412a3 CHECKSIG",
  830. class: PubKeyTy,
  831. },
  832. // tx 599e47a8114fe098103663029548811d2651991b62397e057f0c863c2bc9f9ea
  833. {
  834. name: "Pay PubkeyHash",
  835. script: "DUP HASH160 DATA_20 0x660d4ef3a743e3e696ad990364e555" +
  836. "c271ad504b EQUALVERIFY CHECKSIG",
  837. class: PubKeyHashTy,
  838. },
  839. // part of tx 6d36bc17e947ce00bb6f12f8e7a56a1585c5a36188ffa2b05e10b4743273a74b
  840. // codeseparator parts have been elided. (bitcoin core's checks for
  841. // multisig type doesn't have codesep either).
  842. {
  843. name: "multisig",
  844. script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4" +
  845. "5329a00357b3a7886211ab414d55a 1 CHECKMULTISIG",
  846. class: MultiSigTy,
  847. },
  848. // tx e5779b9e78f9650debc2893fd9636d827b26b4ddfa6a8172fe8708c924f5c39d
  849. {
  850. name: "P2SH",
  851. script: "HASH160 DATA_20 0x433ec2ac1ffa1b7b7d027f564529c57197f" +
  852. "9ae88 EQUAL",
  853. class: ScriptHashTy,
  854. },
  855. {
  856. // Nulldata with no data at all.
  857. name: "nulldata no data",
  858. script: "RETURN",
  859. class: NullDataTy,
  860. },
  861. {
  862. // Nulldata with single zero push.
  863. name: "nulldata zero",
  864. script: "RETURN 0",
  865. class: NullDataTy,
  866. },
  867. {
  868. // Nulldata with small integer push.
  869. name: "nulldata small int",
  870. script: "RETURN 1",
  871. class: NullDataTy,
  872. },
  873. {
  874. // Nulldata with max small integer push.
  875. name: "nulldata max small int",
  876. script: "RETURN 16",
  877. class: NullDataTy,
  878. },
  879. {
  880. // Nulldata with small data push.
  881. name: "nulldata small data",
  882. script: "RETURN DATA_8 0x046708afdb0fe554",
  883. class: NullDataTy,
  884. },
  885. {
  886. // Canonical nulldata with 60-byte data push.
  887. name: "canonical nulldata 60-byte push",
  888. script: "RETURN 0x3c 0x046708afdb0fe5548271967f1a67130b7105cd" +
  889. "6a828e03909a67962e0ea1f61deb649f6bc3f4cef3046708afdb" +
  890. "0fe5548271967f1a67130b7105cd6a",
  891. class: NullDataTy,
  892. },
  893. {
  894. // Non-canonical nulldata with 60-byte data push.
  895. name: "non-canonical nulldata 60-byte push",
  896. script: "RETURN PUSHDATA1 0x3c 0x046708afdb0fe5548271967f1a67" +
  897. "130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
  898. "046708afdb0fe5548271967f1a67130b7105cd6a",
  899. class: NullDataTy,
  900. },
  901. {
  902. // Nulldata with max allowed data to be considered standard.
  903. name: "nulldata max standard push",
  904. script: "RETURN PUSHDATA1 0x50 0x046708afdb0fe5548271967f1a67" +
  905. "130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
  906. "046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
  907. "962e0ea1f61deb649f6bc3f4cef3",
  908. class: NullDataTy,
  909. },
  910. {
  911. // Nulldata with more than max allowed data to be considered
  912. // standard (so therefore nonstandard)
  913. name: "nulldata exceed max standard push",
  914. script: "RETURN PUSHDATA1 0x51 0x046708afdb0fe5548271967f1a67" +
  915. "130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
  916. "046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
  917. "962e0ea1f61deb649f6bc3f4cef308",
  918. class: NonStandardTy,
  919. },
  920. {
  921. // Almost nulldata, but add an additional opcode after the data
  922. // to make it nonstandard.
  923. name: "almost nulldata",
  924. script: "RETURN 4 TRUE",
  925. class: NonStandardTy,
  926. },
  927. // The next few are almost multisig (it is the more complex script type)
  928. // but with various changes to make it fail.
  929. {
  930. // Multisig but invalid nsigs.
  931. name: "strange 1",
  932. script: "DUP DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45" +
  933. "329a00357b3a7886211ab414d55a 1 CHECKMULTISIG",
  934. class: NonStandardTy,
  935. },
  936. {
  937. // Multisig but invalid pubkey.
  938. name: "strange 2",
  939. script: "1 1 1 CHECKMULTISIG",
  940. class: NonStandardTy,
  941. },
  942. {
  943. // Multisig but no matching npubkeys opcode.
  944. name: "strange 3",
  945. script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4532" +
  946. "9a00357b3a7886211ab414d55a DATA_33 0x0232abdc893e7f0" +
  947. "631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a " +
  948. "CHECKMULTISIG",
  949. class: NonStandardTy,
  950. },
  951. {
  952. // Multisig but with multisigverify.
  953. name: "strange 4",
  954. script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4532" +
  955. "9a00357b3a7886211ab414d55a 1 CHECKMULTISIGVERIFY",
  956. class: NonStandardTy,
  957. },
  958. {
  959. // Multisig but wrong length.
  960. name: "strange 5",
  961. script: "1 CHECKMULTISIG",
  962. class: NonStandardTy,
  963. },
  964. {
  965. name: "doesn't parse",
  966. script: "DATA_5 0x01020304",
  967. class: NonStandardTy,
  968. },
  969. {
  970. name: "multisig script with wrong number of pubkeys",
  971. script: "2 " +
  972. "DATA_33 " +
  973. "0x027adf5df7c965a2d46203c781bd4dd8" +
  974. "21f11844136f6673af7cc5a4a05cd29380 " +
  975. "DATA_33 " +
  976. "0x02c08f3de8ee2de9be7bd770f4c10eb0" +
  977. "d6ff1dd81ee96eedd3a9d4aeaf86695e80 " +
  978. "3 CHECKMULTISIG",
  979. class: NonStandardTy,
  980. },
  981. // New standard segwit script templates.
  982. {
  983. // A pay to witness pub key hash pk script.
  984. name: "Pay To Witness PubkeyHash",
  985. script: "0 DATA_20 0x1d0f172a0ecb48aee1be1f2687d2963ae33f71a1",
  986. class: WitnessV0PubKeyHashTy,
  987. },
  988. {
  989. // A pay to witness scripthash pk script.
  990. name: "Pay To Witness Scripthash",
  991. script: "0 DATA_32 0x9f96ade4b41d5433f4eda31e1738ec2b36f6e7d1420d94a6af99801a88f7f7ff",
  992. class: WitnessV0ScriptHashTy,
  993. },
  994. }
  995. // TestScriptClass ensures all the scripts in scriptClassTests have the expected
  996. // class.
  997. func TestScriptClass(t *testing.T) {
  998. for _, test := range scriptClassTests {
  999. script := mustParseShortForm(test.script)
  1000. class := GetScriptClass(script)
  1001. if class != test.class {
  1002. t.Errorf("%s: expected %s got %s (script %x)", test.name,
  1003. test.class, class, script)
  1004. continue
  1005. }
  1006. }
  1007. }
  1008. // TestStringifyClass ensures the script class string returns the expected
  1009. // string for each script class.
  1010. func TestStringifyClass(t *testing.T) {
  1011. tests := []struct {
  1012. name string
  1013. class ScriptClass
  1014. stringed string
  1015. }{
  1016. {
  1017. name: "nonstandardty",
  1018. class: NonStandardTy,
  1019. stringed: "nonstandard",
  1020. },
  1021. {
  1022. name: "pubkey",
  1023. class: PubKeyTy,
  1024. stringed: "pubkey",
  1025. },
  1026. {
  1027. name: "pubkeyhash",
  1028. class: PubKeyHashTy,
  1029. stringed: "pubkeyhash",
  1030. },
  1031. {
  1032. name: "witnesspubkeyhash",
  1033. class: WitnessV0PubKeyHashTy,
  1034. stringed: "witness_v0_keyhash",
  1035. },
  1036. {
  1037. name: "scripthash",
  1038. class: ScriptHashTy,
  1039. stringed: "scripthash",
  1040. },
  1041. {
  1042. name: "witnessscripthash",
  1043. class: WitnessV0ScriptHashTy,
  1044. stringed: "witness_v0_scripthash",
  1045. },
  1046. {
  1047. name: "multisigty",
  1048. class: MultiSigTy,
  1049. stringed: "multisig",
  1050. },
  1051. {
  1052. name: "nulldataty",
  1053. class: NullDataTy,
  1054. stringed: "nulldata",
  1055. },
  1056. {
  1057. name: "broken",
  1058. class: ScriptClass(255),
  1059. stringed: "Invalid",
  1060. },
  1061. }
  1062. for _, test := range tests {
  1063. typeString := test.class.String()
  1064. if typeString != test.stringed {
  1065. t.Errorf("%s: got %#q, want %#q", test.name,
  1066. typeString, test.stringed)
  1067. }
  1068. }
  1069. }
  1070. // TestNullDataScript tests whether NullDataScript returns a valid script.
  1071. func TestNullDataScript(t *testing.T) {
  1072. tests := []struct {
  1073. name string
  1074. data []byte
  1075. expected []byte
  1076. err er.R
  1077. class ScriptClass
  1078. }{
  1079. {
  1080. name: "small int",
  1081. data: hexToBytes("01"),
  1082. expected: mustParseShortForm("RETURN 1"),
  1083. err: nil,
  1084. class: NullDataTy,
  1085. },
  1086. {
  1087. name: "max small int",
  1088. data: hexToBytes("10"),
  1089. expected: mustParseShortForm("RETURN 16"),
  1090. err: nil,
  1091. class: NullDataTy,
  1092. },
  1093. {
  1094. name: "data of size before OP_PUSHDATA1 is needed",
  1095. data: hexToBytes("0102030405060708090a0b0c0d0e0f10111" +
  1096. "2131415161718"),
  1097. expected: mustParseShortForm("RETURN 0x18 0x01020304" +
  1098. "05060708090a0b0c0d0e0f101112131415161718"),
  1099. err: nil,
  1100. class: NullDataTy,
  1101. },
  1102. {
  1103. name: "just right",
  1104. data: hexToBytes("000102030405060708090a0b0c0d0e0f101" +
  1105. "112131415161718191a1b1c1d1e1f202122232425262" +
  1106. "728292a2b2c2d2e2f303132333435363738393a3b3c3" +
  1107. "d3e3f404142434445464748494a4b4c4d4e4f"),
  1108. expected: mustParseShortForm("RETURN PUSHDATA1 0x50 " +
  1109. "0x000102030405060708090a0b0c0d0e0f101112131" +
  1110. "415161718191a1b1c1d1e1f20212223242526272829" +
  1111. "2a2b2c2d2e2f303132333435363738393a3b3c3d3e3" +
  1112. "f404142434445464748494a4b4c4d4e4f"),
  1113. err: nil,
  1114. class: NullDataTy,
  1115. },
  1116. {
  1117. name: "too big",
  1118. data: hexToBytes("000102030405060708090a0b0c0d0e0f101" +
  1119. "112131415161718191a1b1c1d1e1f202122232425262" +
  1120. "728292a2b2c2d2e2f303132333435363738393a3b3c3" +
  1121. "d3e3f404142434445464748494a4b4c4d4e4f50"),
  1122. expected: nil,
  1123. err: txscripterr.ScriptError(txscripterr.ErrTooMuchNullData, ""),
  1124. class: NonStandardTy,
  1125. },
  1126. }
  1127. for i, test := range tests {
  1128. script, err := NullDataScript(test.data)
  1129. if e := tstCheckScriptError(err, test.err); e != nil {
  1130. t.Errorf("NullDataScript: #%d (%s): %v", i, test.name,
  1131. e)
  1132. continue
  1133. }
  1134. // Check that the expected result was returned.
  1135. if !bytes.Equal(script, test.expected) {
  1136. t.Errorf("NullDataScript: #%d (%s) wrong result\n"+
  1137. "got: %x\nwant: %x", i, test.name, script,
  1138. test.expected)
  1139. continue
  1140. }
  1141. // Check that the script has the correct type.
  1142. scriptType := GetScriptClass(script)
  1143. if scriptType != test.class {
  1144. t.Errorf("GetScriptClass: #%d (%s) wrong result -- "+
  1145. "got: %v, want: %v", i, test.name, scriptType,
  1146. test.class)
  1147. continue
  1148. }
  1149. }
  1150. }