Completed
Pull Request — master (#392)
by thomas
191:09 queued 188:38
created

AddressFactory   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 12

Test Coverage

Coverage 82.86%

Importance

Changes 0
Metric Value
dl 0
loc 98
ccs 29
cts 35
cp 0.8286
rs 10
c 0
b 0
f 0
wmc 13
lcom 0
cbo 12

6 Methods

Rating   Name   Duplication   Size   Complexity  
A fromKey() 0 4 1
A fromScript() 0 4 1
A fromOutputScript() 0 14 3
A fromString() 0 14 4
A isValidAddress() 0 11 2
A getAssociatedAddress() 0 10 2
1
<?php
2
3
namespace BitWasp\Bitcoin\Address;
4
5
use BitWasp\Bitcoin\Base58;
6
use BitWasp\Bitcoin\Bitcoin;
7
use BitWasp\Bitcoin\Crypto\EcAdapter\Key\KeyInterface;
8
use BitWasp\Bitcoin\Network\NetworkInterface;
9
use BitWasp\Bitcoin\Script\Classifier\OutputClassifier;
10
use BitWasp\Bitcoin\Script\ScriptInterface;
11
use BitWasp\Bitcoin\Key\PublicKeyFactory;
12
use BitWasp\Buffertools\BufferInterface;
13
14
class AddressFactory
15
{
16
    /**
17
     * Returns a pay-to-pubkey-hash address for the given public key
18
     *
19
     * @param KeyInterface $key
20
     * @return PayToPubKeyHashAddress
21
     */
22 180
    public static function fromKey(KeyInterface $key)
23
    {
24 180
        return new PayToPubKeyHashAddress($key->getPubKeyHash());
25
    }
26
27
    /**
28
     * Takes the $p2shScript and generates the scriptHash address.
29
     *
30
     * @param ScriptInterface $p2shScript
31
     * @return ScriptHashAddress
32
     */
33 42
    public static function fromScript(ScriptInterface $p2shScript)
34
    {
35 42
        return new ScriptHashAddress($p2shScript->getScriptHash());
36
    }
37
38
    /**
39
     * @param ScriptInterface $outputScript
40
     * @return PayToPubKeyHashAddress|ScriptHashAddress
41
     */
42 24
    public static function fromOutputScript(ScriptInterface $outputScript)
43
    {
44 24
        $decode = (new OutputClassifier())->decode($outputScript);
45 24
        switch ($decode->getType()) {
46 24
            case OutputClassifier::PAYTOPUBKEYHASH:
47
                /** @var BufferInterface $solution */
48 12
                return new PayToPubKeyHashAddress($decode->getSolution());
49 18
            case OutputClassifier::PAYTOSCRIPTHASH:
50
                /** @var BufferInterface $solution */
51 6
                return new ScriptHashAddress($decode->getSolution());
52 4
            default:
53 12
                throw new \RuntimeException('Script type is not associated with an address');
54 4
        }
55
    }
56
57
    /**
58
     * @param string $address
59
     * @param NetworkInterface $network
60
     * @return AddressInterface
61
     * @throws \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure
62
     */
63 138
    public static function fromString($address, NetworkInterface $network = null)
64
    {
65 138
        $network = $network ?: Bitcoin::getNetwork();
66 138
        $data = Base58::decodeCheck($address);
67 138
        $prefixByte = $data->slice(0, 1)->getHex();
68
69 138
        if ($prefixByte === $network->getP2shByte()) {
70 24
            return new ScriptHashAddress($data->slice(1));
71 114
        } else if ($prefixByte === $network->getAddressByte()) {
72 108
            return new PayToPubKeyHashAddress($data->slice(1));
73
        } else {
74 6
            throw new \InvalidArgumentException("Invalid prefix [{$prefixByte}]");
75
        }
76
    }
77
78
    /**
79
     * @param string $address
80
     * @param NetworkInterface $network
81
     * @return bool
82
     * @throws \BitWasp\Bitcoin\Exceptions\Base58ChecksumFailure
83
     */
84
    public static function isValidAddress($address, NetworkInterface $network = null)
85
    {
86
        try {
87
            self::fromString($address, $network);
88
            $is_valid = true;
89
        } catch (\Exception $e) {
90
            $is_valid = false;
91
        }
92
93
        return $is_valid;
94
    }
95
96
    /**
97
     * @param ScriptInterface $script
98
     * @return AddressInterface
99
     * @throws \RuntimeException
100
     */
101 12
    public static function getAssociatedAddress(ScriptInterface $script)
102
    {
103 12
        $classifier = new OutputClassifier();
104 12
        $decode = $classifier->decode($script);
105 12
        if ($decode->getType() === OutputClassifier::PAYTOPUBKEY) {
106 6
            return PublicKeyFactory::fromHex($decode->getSolution())->getAddress();
107
        } else {
108 12
            return self::fromOutputScript($script);
109
        }
110
    }
111
}
112