punm parser
This commit is contained in:
368
checking.go
Normal file
368
checking.go
Normal file
@@ -0,0 +1,368 @@
|
||||
package pump_parser
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
)
|
||||
|
||||
func checkBonkGmgnBuy(rawTx *RawTx) bool {
|
||||
|
||||
// 检查交易版本
|
||||
var version, _ = rawTx.Version.(solana.MessageVersion)
|
||||
if version != solana.MessageVersionLegacy {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查交易指令数量
|
||||
if len(rawTx.Transaction.Message.Instructions) != 10 && len(rawTx.Transaction.Message.Instructions) != 9 {
|
||||
return false
|
||||
}
|
||||
accountList := rawTx.getAccountList()
|
||||
// 检查 cu limit
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[0]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.ComputeBudget {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
accountId := accountList[instruction.Accounts[0]].String()
|
||||
if !strings.HasPrefix(accountId, "jitodontfront1111111111151111111111111655") {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 cu price
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[1]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.ComputeBudget {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 ata.createIdempotent
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[2]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SPLAssociatedTokenAccountProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "2" {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) < 4 {
|
||||
return false
|
||||
}
|
||||
|
||||
// gmgn 会先创建 wsol 账户, 而不是 token 账户
|
||||
accountId := accountList[instruction.Accounts[3]]
|
||||
if accountId != solana.WrappedSol {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[3]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 token.syncNative
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[4]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.TokenProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "J" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
offset := 5
|
||||
if len(rawTx.Transaction.Message.Instructions) == 10 {
|
||||
// 检查 ata.create
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[offset]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SPLAssociatedTokenAccountProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "1" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
offset++
|
||||
}
|
||||
|
||||
// 检查 bonk.buy
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[offset]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != raydiumLaunchLabProgramID {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
offset++
|
||||
|
||||
// 检查 token.closeAccount
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[offset]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.TokenProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "A" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
offset++
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[offset]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
offset++
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[offset]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
var (
|
||||
axiomTxLoopupTable = solana.MustPublicKeyFromBase58("7RKtfATWCe98ChuwecNq8XCzAzfoK3DtZTprFsPMGtio")
|
||||
)
|
||||
|
||||
func checkBonkAxiomBuy(rawTx *RawTx) bool {
|
||||
|
||||
// 检查交易版本
|
||||
var version, _ = rawTx.Version.(solana.MessageVersion)
|
||||
if version == solana.MessageVersionLegacy || len(rawTx.Transaction.Message.AddressTableLookups) != 1 {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid transaction version or address table lookups: %v %v %v", rawTx.Transaction.Signatures[0].String(), version, len(rawTx.Transaction.Message.AddressTableLookups))
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查 addressLookupTable 是否是 Axiom 的
|
||||
if rawTx.Transaction.Message.AddressTableLookups[0].AccountKey != axiomTxLoopupTable {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid address lookup table: %v", rawTx.Transaction.Signatures[0].String())
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查交易指令数量
|
||||
if len(rawTx.Transaction.Message.Instructions) != 10 {
|
||||
return false
|
||||
}
|
||||
accountList := rawTx.getAccountList()
|
||||
// 检查 cu limit
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[0]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.ComputeBudget {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for ComputeBudget: %v", programId)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) != 1 {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid number of accounts for ComputeBudget: %v", len(instruction.Accounts))
|
||||
return false
|
||||
}
|
||||
|
||||
accountId := accountList[instruction.Accounts[0]].String()
|
||||
if !strings.HasPrefix(accountId, "jitodontfront") || !strings.HasSuffix(accountId, "TradeWithAxiomDotTrade") {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid account ID for ComputeBudget: %v", accountId)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 cu price
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[1]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.ComputeBudget {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for ComputeBudget: %v", programId)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 ata.createIdempotent
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[2]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SPLAssociatedTokenAccountProgramID {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for SPLAssociatedTokenAccount: %v", programId)
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "2" {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid data for SPLAssociatedTokenAccount: %v", instruction.Data.String())
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) < 4 {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid number of accounts for SPLAssociatedTokenAccount: %v", len(instruction.Accounts))
|
||||
return false
|
||||
}
|
||||
|
||||
// axiom 会先创建 token 账户, 而不是 wsol 账户
|
||||
accountId := accountList[instruction.Accounts[3]]
|
||||
if accountId == solana.WrappedSol {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid account ID for SPLAssociatedTokenAccount, expected token account but got wsol: %v", accountId)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 ata.createIdempotent
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[3]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SPLAssociatedTokenAccountProgramID {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for SPLAssociatedTokenAccount2: %v", programId)
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "2" {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid data for SPLAssociatedTokenAccount2: %v", instruction.Data.String())
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) < 4 {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid number of accounts for SPLAssociatedTokenAccount2: %v", len(instruction.Accounts))
|
||||
return false
|
||||
}
|
||||
|
||||
// axiom 会先创建 token 账户, 而不是 wsol 账户
|
||||
accountId := accountList[instruction.Accounts[3]]
|
||||
if accountId != solana.WrappedSol {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid account ID for SPLAssociatedTokenAccount2, expected wsol but got: %v", accountId)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[4]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for SystemProgram3: %v", programId)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid data for SystemProgram transfer3: %v", instruction.Data)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 token.syncNative
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[5]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.TokenProgramID {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for TokenProgram3: %v", programId)
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "J" {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid data for TokenProgram syncNative3: %v", instruction.Data.String())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 bonk.buy
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[6]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != raydiumLaunchLabProgramID {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 token.closeAccount
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[7]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.TokenProgramID {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for TokenProgram closeAccount: %v", programId)
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "A" {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid data for TokenProgram closeAccount: %v", instruction.Data.String())
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[8]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for SystemProgram transfer4: %v", programId)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid data for SystemProgram transfer4: %v", instruction.Data)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[9]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid program ID for SystemProgram transfer5: %v", programId)
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
log.Printf("CheckBonkAxiomBuy: Invalid data for SystemProgram transfer5: %v", instruction.Data)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user