static public function fromPublicKey($publicKey, $networkId = 104) // 104=mainnet
    {
        // discover public key content
        if ($publicKey instanceof Buffer) {
            $pubKeyBuf = $publicKey; // Buffer to public key
        }
        elseif ($publicKey instanceof KeyPair) {
            $pubKeyBuf = $publicKey->getPublicKey(null); // Keypair to public key
        }
        elseif (is_string($publicKey) && ctype_xdigit($publicKey)) {
            $pubKeyBuf = Buffer::fromHex($publicKey, 32); // Hexadecimal to public key
        }
        elseif (is_string($publicKey) && mb_strlen($publicKey) === 32) {
            $pubKeyBuf = new Buffer($publicKey, 32); // Binary to public key
        }
        else {
            throw new NISInvalidPublicKeyFormat("Could not identify public key format: " . var_export($publicKey, true));
        }

        // discover network name / version byte
        if (is_string($networkId) && !is_numeric($networkId) 
            && in_array(strtolower($networkId), ["mainnet", "testnet", "mijin"])) {
            // network name provided, read version byte from SDK
            $networkId = Network::$networkInfos[strtolower($networkId)]["id"];
        }
        elseif (is_numeric($networkId) && !in_array($networkId, [104, -104, 96])) {
            throw new NISInvalidNetworkId("Invalid netword ID '" . $networkId . "'");
        }
        // network name / version byte is important for address creation
        elseif (is_string($networkId)) {
            throw new NISInvalidNetworkName("Invalid network name '" . $networkId . "'");
        }

        // step 1: keccak-256 hash of the public key
        $pubKeyHash = Encryption::hash("keccak-256", $pubKeyBuf->getBinary(), true); // raw=true

        // step 2: ripemd160 hash of (1)
        $pubKeyRiped = new Buffer(hash("ripemd160", $pubKeyHash, true), 20);

        // step 3: add version byte in front of (2)
        $networkPrefix = Network::getPrefixFromId($networkId);
        $versionPrefixedPubKey = Buffer::fromHex($networkPrefix . $pubKeyRiped->getHex());

        // step 4: get the checksum of (3)
        $checksum = Encryption::checksum("keccak-256", $versionPrefixedPubKey, 4); // checksumLen=4

        // step 5: concatenate (3) and (4)
        $addressHash = $versionPrefixedPubKey->getHex() . $checksum->getHex();
        $hashBuf = Buffer::fromHex($addressHash);
        $encodedAddress = hex2bin($addressHash);

        // step 6: base32 encode (5)
        $encodedBase32  = new Buffer(Base32::encode($encodedAddress), Address::BYTES);

        return new Address([
            "address" => $encodedBase32->getBinary(),
            "publicKey" => $pubKeyBuf->getHex(),
        ]);
    }