| 260 | } |
| 261 | |
| 262 | func GetProgramInfo(program []byte) (ProgramInfo, error) { |
| 263 | info := ProgramInfo{} |
| 264 | |
| 265 | if len(program) <= 2 { |
| 266 | return info, errors.New("wrong program") |
| 267 | } |
| 268 | |
| 269 | end := program[len(program)-1] |
| 270 | if end == byte(neovm.CHECKSIG) { |
| 271 | parser := programParser{source: common.NewZeroCopySource(program[:len(program)-1])} |
| 272 | pubkey, err := parser.ReadPubKey() |
| 273 | if err != nil { |
| 274 | return info, err |
| 275 | } |
| 276 | err = parser.ExpectEOF() |
| 277 | if err != nil { |
| 278 | return info, err |
| 279 | } |
| 280 | info.PubKeys = append(info.PubKeys, pubkey) |
| 281 | info.M = 1 |
| 282 | |
| 283 | return info, nil |
| 284 | } else if end == byte(neovm.CHECKMULTISIG) { |
| 285 | parser := programParser{source: common.NewZeroCopySource(program)} |
| 286 | m, err := parser.ReadNum() |
| 287 | if err != nil { |
| 288 | return info, err |
| 289 | } |
| 290 | for i := 0; i < int(m); i++ { |
| 291 | key, err := parser.ReadPubKey() |
| 292 | if err != nil { |
| 293 | return info, err |
| 294 | } |
| 295 | info.PubKeys = append(info.PubKeys, key) |
| 296 | } |
| 297 | var buffers [][]byte |
| 298 | for { |
| 299 | code, err := parser.PeekOpCode() |
| 300 | if err != nil { |
| 301 | return info, err |
| 302 | } |
| 303 | |
| 304 | if code == neovm.CHECKMULTISIG { |
| 305 | parser.ReadOpCode() |
| 306 | break |
| 307 | } else if code == neovm.PUSH0 { |
| 308 | parser.ReadOpCode() |
| 309 | bint := big.NewInt(0) |
| 310 | buffers = append(buffers, common.BigIntToNeoBytes(bint)) |
| 311 | } else if num := int(code) - int(neovm.PUSH1) + 1; 1 <= num && num <= 16 { |
| 312 | parser.ReadOpCode() |
| 313 | bint := big.NewInt(int64(num)) |
| 314 | buffers = append(buffers, common.BigIntToNeoBytes(bint)) |
| 315 | } else { |
| 316 | buff, err := parser.ReadBytes() |
| 317 | if err != nil { |
| 318 | return info, err |
| 319 | } |